1818#endif
1919
2020int global_array [12 ];
21+ int global_multi_array [12 ][34 ];
22+ int global_num ;
2123
2224void test_parsing_failures () {
2325 (void )_Countof ; // expected-error {{expected expression}}
@@ -36,6 +38,12 @@ void test_semantic_failures() {
3638 expected-note {{forward declaration of 'struct S'}}
3739 struct T { int x ; };
3840 (void )_Countof (struct T ); // expected-error {{'_Countof' requires an argument of array type; 'struct T' invalid}}
41+ struct U { int x [3 ]; };
42+ (void )_Countof (struct U ); // expected-error {{'_Countof' requires an argument of array type; 'struct U' invalid}}
43+ int a [3 ];
44+ (void )_Countof (& a ); // expected-error {{'_Countof' requires an argument of array type; 'int (*)[3]' invalid}}
45+ int * p ;
46+ (void )_Countof (p ); // expected-error {{'_Countof' requires an argument of array type; 'int *' invalid}}
3947}
4048
4149void test_constant_expression_behavior (int n ) {
@@ -81,6 +89,22 @@ void test_with_function_param(int array[12], int (*array_ptr)[12], int static_ar
8189 (void )_Countof (static_array ); // expected-error {{'_Countof' requires an argument of array type; 'int *' invalid}}
8290}
8391
92+ void test_func_fix_fix (int i , char (* a )[3 ][5 ], int (* x )[_Countof (* a )], char (* )[_Generic(x , int (* )[3 ]: 1 )]); // expected-note {{passing argument to parameter}}
93+ void test_func_fix_var (int i , char (* a )[3 ][i ], int (* x )[_Countof (* a )], char (* )[_Generic(x , int (* )[3 ]: 1 )]); // expected-note {{passing argument to parameter}}
94+ void test_func_fix_uns (int i , char (* a )[3 ][* ], int (* x )[_Countof (* a )], char (* )[_Generic(x , int (* )[3 ]: 1 )]); // expected-note {{passing argument to parameter}}
95+
96+ void test_funcs () {
97+ int i3 [3 ];
98+ int i5 [5 ];
99+ char c35 [3 ][5 ];
100+ test_func_fix_fix (5 , & c35 , & i3 );
101+ test_func_fix_fix (5 , & c35 , & i5 ); // expected-warning {{incompatible pointer types passing 'int (*)[5]' to parameter of type 'int (*)[3]'}}
102+ test_func_fix_var (5 , & c35 , & i3 );
103+ test_func_fix_var (5 , & c35 , & i5 ); // expected-warning {{incompatible pointer types passing 'int (*)[5]' to parameter of type 'int (*)[3]'}}
104+ test_func_fix_uns (5 , & c35 , & i3 );
105+ test_func_fix_uns (5 , & c35 , & i5 ); // expected-warning {{incompatible pointer types passing 'int (*)[5]' to parameter of type 'int (*)[3]'}}
106+ }
107+
84108void test_multidimensional_arrays () {
85109 int array [12 ][7 ];
86110 static_assert (_Countof (array ) == 12 );
@@ -102,6 +126,11 @@ void test_unspecified_array_length() {
102126 static_assert (_Countof (* * x ) == 3 );
103127}
104128
129+ void test_completed_array () {
130+ int a [] = {1 , 2 , global_num };
131+ static_assert (_Countof (a ) == 3 );
132+ }
133+
105134// Test that the return type of _Countof is what you'd expect (size_t).
106135void test_return_type () {
107136 static_assert (_Generic (typeof (_Countof global_array ), typeof (sizeof (0 )) : 1 , default : 0 ));
@@ -121,10 +150,14 @@ void test_typedefs() {
121150 static_assert (_Countof (* x ) == 12 );
122151}
123152
124- void test_zero_size_arrays () {
153+ void test_zero_size_arrays (int n ) {
125154 int array [0 ]; // expected-warning {{zero size arrays are an extension}}
126155 static_assert (_Countof (array ) == 0 );
127156 static_assert (_Countof (int [0 ]) == 0 ); // expected-warning {{zero size arrays are an extension}}
157+ int multi_array [0 ][n ]; // FIXME: Should trigger -Wzero-length-array
158+ static_assert (_Countof (multi_array ) == 0 );
159+ int another_one [0 ][3 ]; // expected-warning {{zero size arrays are an extension}}
160+ static_assert (_Countof (another_one ) == 0 );
128161}
129162
130163void test_struct_members () {
@@ -144,3 +177,18 @@ void test_compound_literals() {
144177 static_assert (_Countof ((int [2 ]){}) == 2 );
145178 static_assert (_Countof ((int []){1 , 2 , 3 , 4 }) == 4 );
146179}
180+
181+ /* We don't get a diagnostic for test_f1(), because it ends up unused
182+ * as _Countof() results in an integer constant expression, which is not
183+ * evaluated. However, test_f2() ends up being evaluated, since 'a' is
184+ * a VLA.
185+ */
186+ static int test_f1 ();
187+ static int test_f2 (); // FIXME: Should trigger function 'test_f2' has internal linkage but is not defined
188+
189+ void test_symbols () {
190+ int a [global_num ][global_num ];
191+
192+ static_assert (_Countof (global_multi_array [test_f1 ()]) == 34 );
193+ (void )_Countof (a [test_f2 ()]);
194+ }
0 commit comments