xref: /llvm-project/clang/test/C/C23/n3007.c (revision 50c81128de8616117118564eff22cf508cba7848)
1 // RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
2 
3 /* WG14 N3007: Yes
4  * Type Inference for object definitions
5  */
test_auto_int(void)6 void test_auto_int(void) {
7   auto int auto_int = 12;
8 }
9 
test_qualifiers(int x,const int y,int * restrict z)10 void test_qualifiers(int x, const int y, int * restrict z) {
11   const auto a = x;
12   auto b = y;
13   static auto c = 1UL;
14   int* pa = &a; // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
15   const int* pb = &b;
16   int* pc = &c; // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
17 
18   const int ci = 12;
19   auto yup = ci;
20   yup = 12;
21 
22   auto r_test = z;
23 
24   _Static_assert(_Generic(a, int : 1));
25   _Static_assert(_Generic(c, unsigned long : 1));
26   _Static_assert(_Generic(pa, int * : 1));
27   _Static_assert(_Generic(pb, const int * : 1));
28   _Static_assert(_Generic(r_test, int * : 1));
29 }
30 
test_atomic(void)31 void test_atomic(void) {
32   _Atomic auto i = 12;  // expected-error {{_Atomic cannot be applied to type 'auto' in C23}}
33   _Atomic(auto) j = 12; // expected-error {{'auto' not allowed here}} \
34                            expected-error {{a type specifier is required for all declarations}}
35 
36   _Atomic(int) foo(void);
37   auto k = foo();
38 
39   _Static_assert(_Generic(&i, _Atomic auto *: 1)); // expected-error {{_Atomic cannot be applied to type 'auto' in C23}} \
40                                                       expected-error {{'auto' not allowed here}}
41   _Static_assert(_Generic(k, int: 1));
42 }
43 
test_double(void)44 void test_double(void) {
45   double A[3] = { 0 };
46   auto pA = A;
47   auto qA = &A;
48   auto pi = 3.14;
49 
50   _Static_assert(_Generic(A, double * : 1));
51   _Static_assert(_Generic(pA, double * : 1));
52   _Static_assert(_Generic(qA, double (*)[3] : 1));
53   _Static_assert(_Generic(pi, double : 1));
54 }
55 
test_auto_param(auto a)56 int test_auto_param(auto a) { // expected-error {{'auto' not allowed in function prototype}}
57   return (int)(a * 2);
58 }
59 
test_auto_return(float a,int b)60 auto test_auto_return(float a, int b) { // expected-error {{'auto' not allowed in function return type}}
61   return ((a * b) * (a / b));
62 }
63 
test(auto x)64 [[clang::overloadable]] auto test(auto x) { // expected-error {{'auto' not allowed in function prototype}} \
65                                                expected-error {{'auto' not allowed in function return type}}
66   return x;
67 }
68 
test_sizeof_alignas(void)69 void test_sizeof_alignas(void) {
70   (void)sizeof(auto);       // expected-error {{expected expression}}
71   _Alignas(auto) int a[4];  // expected-error {{expected expression}}
72 }
73 
test_arrary(void)74 void test_arrary(void) {
75   auto a[4];          // expected-error {{'auto' not allowed in array declaration}}
76   auto b[] = {1, 2};  // expected-error {{cannot use 'auto' with array in C}}
77 }
78 
test_initializer_list(void)79 void test_initializer_list(void) {
80   auto a = {};        // expected-error {{cannot use 'auto' with array in C}}
81   auto b = { 0 };     // expected-error {{cannot use 'auto' with array in C}}
82   auto c = { 1, };    // expected-error {{cannot use 'auto' with array in C}}
83   auto d = { 1 , 2 }; // expected-error {{cannot use 'auto' with array in C}}
84   auto e = (int [3]){ 1, 2, 3 };
85 }
86 
test_structs(void)87 void test_structs(void) {
88   // FIXME: Both of these should be diagnosed as invalid underspecified
89   // declarations as described in N3006.
90   auto p1 = (struct { int a; } *)0;
91   struct s;
92   auto p2 = (struct s { int a; } *)0;
93 
94   struct B { auto b; };   // expected-error {{'auto' not allowed in struct member}}
95 }
96 
test_typedefs(void)97 void test_typedefs(void) {
98   typedef auto auto_type;   // expected-error {{'auto' not allowed in typedef}}
99 
100   typedef auto (*fp)(void); // expected-error {{'auto' not allowed in typedef}}
101   typedef void (*fp)(auto); // expected-error {{'auto' not allowed in function prototype}}
102 
103   _Generic(0, auto : 1);    // expected-error {{'auto' not allowed here}}
104 }
105 
test_misc(void)106 void test_misc(void) {
107   auto something;                           // expected-error {{declaration of variable 'something' with deduced type 'auto' requires an initializer}}
108   auto test_char = 'A';
109   auto test_char_ptr = "test";
110   auto test_char_ptr2[] = "another test";   // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
111   auto auto_size = sizeof(auto);            // expected-error {{expected expression}}
112 
113   _Static_assert(_Generic(test_char, int : 1));
114   _Static_assert(_Generic(test_char_ptr, char * : 1));
115   _Static_assert(_Generic(test_char_ptr2, char * : 1));
116 }
117 
test_no_integer_promotions(void)118 void test_no_integer_promotions(void) {
119   short s;
120   auto a = s;
121   _Generic(a, int : 1); // expected-error {{controlling expression type 'short' not compatible with any generic association type}}
122 }
123 
test_compound_literals(void)124 void test_compound_literals(void) {
125   auto a = (int){};
126   auto b = (int){ 0 };
127   auto c = (int){ 0, };
128   auto d = (int){ 0, 1 };       // expected-warning {{excess elements in scalar initializer}}
129 
130   auto auto_cl = (auto){13};    // expected-error {{expected expression}}
131 
132   _Static_assert(_Generic(a, int : 1));
133   _Static_assert(_Generic(b, int : 1));
134   _Static_assert(_Generic(c, int : 1));
135 }
136 
test_pointers(void)137 void test_pointers(void) {
138   int a;
139   auto *ptr = &a; // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
140   auto *ptr2 = a; // expected-error {{variable 'ptr2' with type 'auto *' has incompatible initializer of type 'int'}} \
141                      expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
142   auto nptr = nullptr;
143 
144   _Static_assert(_Generic(ptr, int * : 1));
145   _Static_assert(_Generic(ptr2, int * : 1));
146 }
147 
test_scopes(void)148 void test_scopes(void) {
149   double a = 7;
150   double b = 9;
151   {
152     auto a = a * a; // expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}} \
153                        expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
154   }
155   {
156     auto b = a * a;
157     auto a = b;
158 
159     _Static_assert(_Generic(a, double : 1));
160     _Static_assert(_Generic(b, double : 1));
161   }
162 }
163 
test_loop(void)164 void test_loop(void) {
165   auto j = 4;
166   for (auto i = j; i < 2 * j; i++);
167 
168   _Static_assert(_Generic(j, int : 1));
169 }
170 
171 #define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
172 auto _NAME = ARG + (ARG2 / ARG3);
173 
174 // This macro should only work with integers due to the usage of binary operators
175 #define AUTO_INT_MACRO(_NAME, ARG, ARG2, ARG3) \
176 auto _NAME = (ARG ^ ARG2) & ARG3;
177 
test_macros(int in_int)178 void test_macros(int in_int) {
179   auto a = in_int + 1;
180   AUTO_MACRO(b, 1.3, 2.5f, 3);
181   AUTO_INT_MACRO(c, 64, 23, 0xff);
182   AUTO_INT_MACRO(not_valid, 51.5, 25, 0xff); // expected-error {{invalid operands to binary expression ('double' and 'int')}}
183 
184   auto result = (a + (int)b) - c;
185 
186   _Static_assert(_Generic(a, int : 1));
187   _Static_assert(_Generic(b, double : 1));
188   _Static_assert(_Generic(c, int : 1));
189   _Static_assert(_Generic(result, int : 1));
190 }
191