Skip to content

Commit f4f1f56

Browse files
Add more tests for _Countof
Link: <#102836> Link: <#133125> Cc: Aaron Ballman <aaron@aaronballman.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
1 parent f338216 commit f4f1f56

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

clang/test/C/C2y/n3369.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
#error "Expected to have _Countof support"
1818
#endif
1919

20+
#define NULL ((void *) 0)
21+
2022
int global_array[12];
23+
int global_multi_array[12][34];
24+
int global_num;
2125

2226
void 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

4151
void 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+
84110
void 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).
106137
void 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

130165
void 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

Comments
 (0)