197 lines · c
1// RUN: %clang_cc1 -fsyntax-only -std=c2y -pedantic -Wall -Wno-comment -verify %s2// RUN: %clang_cc1 -fsyntax-only -std=c2y -pedantic -Wall -Wno-comment -fexperimental-new-constant-interpreter -verify %s3 4/* WG14 N3369: Clang 215 * _Lengthof operator6 *7 * Adds an operator to get the length of an array. Note that WG14 N3469 renamed8 * this operator to _Countof.9 */10 11#if !__has_feature(c_countof)12#error "Expected to have _Countof support"13#endif14 15#if !__has_extension(c_countof)16// __has_extension returns true if __has_feature returns true.17#error "Expected to have _Countof support"18#endif19 20#define NULL ((void *) 0)21 22int global_array[12];23int global_multi_array[12][34];24int global_num;25 26void test_parsing_failures() {27 (void)_Countof; // expected-error {{expected expression}}28 (void)_Countof(; // expected-error {{expected expression}}29 (void)_Countof(); // expected-error {{expected expression}}30 (void)_Countof int; // expected-error {{expected expression}}31}32 33void test_semantic_failures() {34 (void)_Countof(1); // expected-error {{'_Countof' requires an argument of array type; 'int' invalid}}35 int non_array;36 (void)_Countof non_array; // expected-error {{'_Countof' requires an argument of array type; 'int' invalid}} 37 (void)_Countof(int); // expected-error {{'_Countof' requires an argument of array type; 'int' invalid}} 38 (void)_Countof(test_semantic_failures); // expected-error {{invalid application of '_Countof' to a function type}}39 (void)_Countof(struct S); // expected-error {{invalid application of '_Countof' to an incomplete type 'struct S'}} \40 expected-note {{forward declaration of 'struct S'}}41 struct T { int x; };42 (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}}49}50 51void test_constant_expression_behavior(int n) {52 static_assert(_Countof(global_array) == 12);53 static_assert(_Countof global_array == 12); 54 static_assert(_Countof(int[12]) == 12);55 56 // Use of a VLA makes it not a constant expression, same as with sizeof.57 int array[n];58 static_assert(_Countof(array)); // expected-error {{static assertion expression is not an integral constant expression}}59 static_assert(sizeof(array)); // expected-error {{static assertion expression is not an integral constant expression}}60 static_assert(_Countof(int[n]));// expected-error {{static assertion expression is not an integral constant expression}}61 static_assert(sizeof(int[n])); // expected-error {{static assertion expression is not an integral constant expression}}62 63 // Constant folding works the same way as sizeof, too.64 const int m = 12;65 int other_array[m];66 static_assert(sizeof(other_array)); // expected-error {{static assertion expression is not an integral constant expression}}67 static_assert(_Countof(other_array)); // expected-error {{static assertion expression is not an integral constant expression}}68 static_assert(sizeof(int[m])); // expected-error {{static assertion expression is not an integral constant expression}}69 static_assert(_Countof(int[m])); // expected-error {{static assertion expression is not an integral constant expression}}70 71 // Note that this applies to each array dimension.72 int another_array[n][7];73 static_assert(_Countof(another_array)); // expected-error {{static assertion expression is not an integral constant expression}}74 static_assert(_Countof(*another_array) == 7);75 76 // Only the first dimension is needed for constant evaluation; other77 // dimensions can be ignored.78 int yet_another_array[7][n];79 static_assert(_Countof(yet_another_array) == 7);80 static_assert(_Countof(*yet_another_array)); // expected-error {{static assertion expression is not an integral constant expression}}81 82 int one_more_time[n][n][7];83 static_assert(_Countof(one_more_time)); // expected-error {{static assertion expression is not an integral constant expression}}84 static_assert(_Countof(*one_more_time)); // expected-error {{static assertion expression is not an integral constant expression}}85 static_assert(_Countof(**one_more_time) == 7);86}87 88void test_with_function_param(int array[12], int (*array_ptr)[12], int static_array[static 12]) {89 (void)_Countof(array); // expected-error {{'_Countof' requires an argument of array type; 'int *' invalid}}90 static_assert(_Countof(*array_ptr) == 12);91 (void)_Countof(static_array); // expected-error {{'_Countof' requires an argument of array type; 'int *' invalid}}92}93 94void 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}}95void 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}}96void 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 98void 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-error {{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-error {{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-error {{incompatible pointer types passing 'int (*)[5]' to parameter of type 'int (*)[3]'}}108}109 110void test_multidimensional_arrays() {111 int array[12][7];112 static_assert(_Countof(array) == 12);113 static_assert(_Countof(*array) == 7);114 115 int mdarray[12][7][100][3];116 static_assert(_Countof(mdarray) == 12);117 static_assert(_Countof(*mdarray) == 7);118 static_assert(_Countof(**mdarray) == 100);119 static_assert(_Countof(***mdarray) == 3);120}121 122void test_unspecified_array_length() {123 static_assert(_Countof(int[])); // expected-error {{invalid application of '_Countof' to an incomplete type 'int[]'}}124 125 extern int x[][6][3];126 static_assert(_Countof(x)); // expected-error {{invalid application of '_Countof' to an incomplete type 'int[][6][3]'}}127 static_assert(_Countof(*x) == 6);128 static_assert(_Countof(**x) == 3);129}130 131void test_completed_array() {132 int a[] = {1, 2, global_num};133 static_assert(_Countof(a) == 3);134}135 136// Test that the return type of _Countof is what you'd expect (size_t).137void test_return_type() {138 static_assert(_Generic(typeof(_Countof global_array), typeof(sizeof(0)) : 1, default : 0));139}140 141// Test that _Countof is able to look through typedefs.142void test_typedefs() {143 typedef int foo[12];144 foo f;145 static_assert(_Countof(foo) == 12);146 static_assert(_Countof(f) == 12);147 148 // Ensure multidimensional arrays also work.149 foo x[100];150 static_assert(_Generic(typeof(x), int[100][12] : 1, default : 0));151 static_assert(_Countof(x) == 100);152 static_assert(_Countof(*x) == 12);153}154 155void test_zero_size_arrays(int n) {156 int array[0]; // expected-warning {{zero size arrays are an extension}}157 static_assert(_Countof(array) == 0);158 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-array160 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);163}164 165void test_struct_members() {166 struct S {167 int array[10];168 } s;169 static_assert(_Countof(s.array) == 10);170 171 struct T {172 int count;173 int fam[];174 } t;175 static_assert(_Countof(t.fam)); // expected-error {{invalid application of '_Countof' to an incomplete type 'int[]'}}176}177 178void test_compound_literals() {179 static_assert(_Countof((int[2]){}) == 2);180 static_assert(_Countof((int[]){1, 2, 3, 4}) == 4); 181}182 183/* We don't get a diagnostic for test_f1(), because it ends up unused184 * as _Countof() results in an integer constant expression, which is not185 * evaluated. However, test_f2() ends up being evaluated, since 'a' is186 * a VLA.187 */188static int test_f1();189static int test_f2(); // FIXME: Should trigger function 'test_f2' has internal linkage but is not defined190 191void 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}197