1717#error "Expected to have _Countof support"
1818#endif
1919
20+ #define NULL ((void *) 0)
21+
2022int global_array [12 ];
23+ int global_multi_array [12 ][34 ];
24+ int global_num ;
2125
2226void test_parsing_failures () {
2327 (void )_Countof ; // expected-error {{expected expression}}
@@ -36,6 +40,12 @@ void test_semantic_failures() {
3640 expected-note {{forward declaration of 'struct S'}}
3741 struct T { int x ; };
3842 (void )_Countof (struct T ); // expected-error {{'_Countof' requires an argument of array type; 'struct T' invalid}}
43+ struct U { int x [3 ]; };
44+ (void )_Countof (struct U ); // expected-error {{'_Countof' requires an argument of array type; 'struct U' invalid}}
45+ int a [3 ];
46+ (void )_Countof (& a ); // expected-error {{'_Countof' requires an argument of array type; 'int (*)[3]' invalid}}
47+ int * p ;
48+ (void )_Countof (p ); // expected-error {{'_Countof' requires an argument of array type; 'int *' invalid}}
3949}
4050
4151void test_constant_expression_behavior (int n ) {
@@ -81,6 +91,22 @@ void test_with_function_param(int array[12], int (*array_ptr)[12], int static_ar
8191 (void )_Countof (static_array ); // expected-error {{'_Countof' requires an argument of array type; 'int *' invalid}}
8292}
8393
94+ 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}}
95+ 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}}
96+ 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}}
97+
98+ void test_funcs () {
99+ int i3 [3 ];
100+ int i5 [5 ];
101+ char c35 [3 ][5 ];
102+ test_func_fix_fix (5 , & c35 , & i3 , NULL );
103+ test_func_fix_fix (5 , & c35 , & i5 , NULL ); // expected-warning {{incompatible pointer types passing 'int (*)[5]' to parameter of type 'int (*)[3]'}}
104+ test_func_fix_var (5 , & c35 , & i3 , NULL );
105+ test_func_fix_var (5 , & c35 , & i5 , NULL ); // expected-warning {{incompatible pointer types passing 'int (*)[5]' to parameter of type 'int (*)[3]'}}
106+ test_func_fix_uns (5 , & c35 , & i3 , NULL );
107+ test_func_fix_uns (5 , & c35 , & i5 , NULL ); // expected-warning {{incompatible pointer types passing 'int (*)[5]' to parameter of type 'int (*)[3]'}}
108+ }
109+
84110void test_multidimensional_arrays () {
85111 int array [12 ][7 ];
86112 static_assert (_Countof (array ) == 12 );
@@ -102,6 +128,11 @@ void test_unspecified_array_length() {
102128 static_assert (_Countof (* * x ) == 3 );
103129}
104130
131+ void test_completed_array () {
132+ int a [] = {1 , 2 , global_num };
133+ static_assert (_Countof (a ) == 3 );
134+ }
135+
105136// Test that the return type of _Countof is what you'd expect (size_t).
106137void test_return_type () {
107138 static_assert (_Generic (typeof (_Countof global_array ), typeof (sizeof (0 )) : 1 , default : 0 ));
@@ -121,10 +152,14 @@ void test_typedefs() {
121152 static_assert (_Countof (* x ) == 12 );
122153}
123154
124- void test_zero_size_arrays () {
155+ void test_zero_size_arrays (int n ) {
125156 int array [0 ]; // expected-warning {{zero size arrays are an extension}}
126157 static_assert (_Countof (array ) == 0 );
127158 static_assert (_Countof (int [0 ]) == 0 ); // expected-warning {{zero size arrays are an extension}}
159+ int multi_array [0 ][n ]; // FIXME: Should trigger -Wzero-length-array
160+ static_assert (_Countof (multi_array ) == 0 );
161+ int another_one [0 ][3 ]; // expected-warning {{zero size arrays are an extension}}
162+ static_assert (_Countof (another_one ) == 0 );
128163}
129164
130165void test_struct_members () {
@@ -144,3 +179,18 @@ void test_compound_literals() {
144179 static_assert (_Countof ((int [2 ]){}) == 2 );
145180 static_assert (_Countof ((int []){1 , 2 , 3 , 4 }) == 4 );
146181}
182+
183+ /* We don't get a diagnostic for test_f1(), because it ends up unused
184+ * as _Countof() results in an integer constant expression, which is not
185+ * evaluated. However, test_f2() ends up being evaluated, since 'a' is
186+ * a VLA.
187+ */
188+ static int test_f1 ();
189+ static int test_f2 (); // FIXME: Should trigger function 'test_f2' has internal linkage but is not defined
190+
191+ void test_symbols () {
192+ int a [global_num ][global_num ];
193+
194+ static_assert (_Countof (global_multi_array [test_f1 ()]) == 34 );
195+ (void )_Countof (a [test_f2 ()]);
196+ }
0 commit comments