xref: /llvm-project/clang/test/SemaCXX/paren-list-agg-init.cpp (revision 26baa00908b2eb8b2925800af6bc64fbe53cac48)
1 // RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
2 // RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only -fexperimental-new-constant-interpreter
3 // RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only -fexperimental-new-constant-interpreter
4 // RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only
5 
6 struct A { // expected-note 4{{candidate constructor}}
7   char i;
8   double j;
9 };
10 
11 struct B {
12   A a;
13   int b[20];
14   int &&c;
15 };
16 
17 struct C { // expected-note 5{{candidate constructor}}
18   A a;
19   int b[20];
20 };
21 
22 struct D : public C, public A {
23   int a;
24 };
25 
26 struct E {
27   struct F { // expected-note 2{{candidate constructor}}
28     F(int, int); // expected-note {{candidate constructor}}
29   };
30   int a;
31   F f;
32 };
33 
34 int getint(); // expected-note {{declared here}}
35 
36 struct F {
37   int a;
38   int b = getint(); // expected-note {{non-constexpr function 'getint' cannot be used in a constant expression}}
39 };
40 
41 template <typename T>
42 struct G {
43   T t1;
44   T t2;
45 };
46 
47 struct H {
48   virtual void foo() = 0;
49 };
50 
51 struct I : public H { // expected-note 3{{candidate constructor}}
52   int i, j;
53   void foo() override {}
54 };
55 
56 struct J {
57   int a;
58   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
59 };
60 
61 enum K { K0, K1, K2 };
62 
63 struct L {
64   K k : 1;
65 };
66 
67 struct M {
68   struct N {
69     private:
70     N(int);
71     // expected-note@-1 {{declared private here}}
72   };
73   int i;
74   N n;
75 };
76 
77 union U {
78   int a;
79   char* b;
80 };
81 
82 template <typename T, char CH>
83 void bar() {
84   T t = 0;
85   A a(CH, 1.1); // OK; C++ paren list constructors are supported in semantic tree transformations.
86   // beforecxx20-warning@-1 2{{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
87 }
88 
89 template <class T, class... Args>
90 T Construct(Args... args) {
91   return T(args...); // OK; variadic arguments can be used in paren list initializers.
92   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
93 }
94 
95 void foo(int n) { // expected-note {{declared here}}
96   A a1(1954, 9, 21);
97   // expected-error@-1 {{excess elements in struct initializer}}
98   A a2(2.1);
99   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
100   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
101   A a3(-1.2, 9.8);
102   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
103   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
104   A a4 = static_cast<A>(1.1);
105   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
106   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
107   A a5 = (A)3.1;
108   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
109   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
110   A a6 = A(8.7);
111   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
112   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
113 
114   B b1(2022, {7, 8});
115   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
116   B b2(A(1), {}, 1);
117   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
118   // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
119   // expected-warning@-3 {{temporary whose address is used as value of local variable 'b2' will be destroyed at the end of the full-expression}}
120 
121   C c(A(1), 1, 2, 3, 4);
122   // expected-error@-1 {{array initializer must be an initializer list}}
123   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
124   D d1(1);
125   // expected-error@-1 {{no viable conversion from 'int' to 'C'}}
126   D d2(C(1));
127   // expected-error@-1 {{no matching conversion for functional-style cast from 'int' to 'C'}}
128   // beforecxx20-warning@-2 {{aggregate initialization of type 'D' from a parenthesized list of values is a C++20 extension}}
129   D d3(C(A(1)), 1);
130   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
131   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
132   // beforecxx20-warning@-3 {{aggregate initialization of type 'C' from a parenthesized list of values is a C++20 extension}}
133 
134   int arr1[](0, 1, 2, A(1));
135   // expected-error@-1 {{no viable conversion from 'A' to 'int'}}
136   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
137 
138   int arr2[2](0, 1, 2);
139   // expected-error@-1 {{excess elements in array initializer}}
140 
141   // We should not build paren list initilizations for IK_COPY.
142   int arr3[1] = 1;
143   // expected-error@-1 {{array initializer must be an initializer list}}
144 
145   U u1("abcd");
146   // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}
147   U u2(1, "efgh");
148   // expected-error@-1 {{excess elements in union initializer}}
149 
150   E e1(1);
151   // expected-error@-1 {{no matching constructor for initialization of 'F'}}
152 
153   constexpr F f1(1);
154   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
155   // beforecxx20-warning@-2 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
156 
157   constexpr F f2(1, 1); // OK: f2.b is initialized by a constant expression.
158   // beforecxx20-warning@-1 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
159 
160   bar<int, 'a'>();
161   // beforecxx20-note@-1 {{in instantiation of function template specialization 'bar<int, 'a'>' requested here}}
162 
163   G<char> g('b', 'b');
164   // beforecxx20-warning@-1 {{aggregate initialization of type 'G<char>' from a parenthesized list of values is a C++20 extension}}
165 
166   A a7 = Construct<A>('i', 2.2);
167   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct<A, char, double>' requested here}}
168 
169   L l(K::K2);
170   // expected-warning@-1 {{implicit truncation}}
171   // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
172 
173   int arr4[](1, 2);
174   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
175 
176   int arr5[2](1, 2);
177   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
178 
179   int arr6[n](1, 2, 3); // expected-warning {{variable length arrays in C++ are a Clang extension}} \
180                            expected-note {{function parameter 'n' with unknown value cannot be used in a constant expression}} \
181                            expected-error {{variable-sized object may not be initialized}}
182 
183   I i(1, 2);
184   // expected-error@-1 {{no matching constructor for initialization of 'I'}}
185 
186   J j(1, {2, 3});
187   // expected-error@-1 {{initialization of flexible array member is not allowed}}
188 
189   M m(1, 1);
190   // expected-error@-1 {{field of type 'N' has private constructor}}
191   // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
192 
193   static_assert(__is_trivially_constructible(A, char, double));
194   static_assert(__is_trivially_constructible(A, char, int));
195   static_assert(__is_trivially_constructible(A, char));
196 
197   static_assert(__is_trivially_constructible(D, C, A, int));
198   static_assert(__is_trivially_constructible(D, C));
199 
200   static_assert(__is_trivially_constructible(int[2], int, int));
201   static_assert(__is_trivially_constructible(int[2], int, double));
202   static_assert(__is_trivially_constructible(int[2], int));
203 }
204 
205 namespace gh59675 {
206 struct K {
207   template <typename T>
208   K(T);
209 
210   virtual ~K();
211 };
212 
213 union V {
214   K k;
215   // expected-note@-1 {{default constructor of 'V' is implicitly deleted because field 'k' has no default constructor}}
216   // expected-note@-2 2{{copy constructor of 'V' is implicitly deleted because variant field 'k' has a non-trivial copy constructor}}
217 };
218 
219 static_assert(!__is_constructible(V, const V&));
220 static_assert(!__is_constructible(V, V&&));
221 
222 void bar() {
223   V v1;
224   // expected-error@-1 {{call to implicitly-deleted default constructor of 'V'}}
225 
226   V v2(v1);
227   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
228 
229   V v3((V&&) v1);
230   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
231 }
232 }
233 
234 namespace gh62296 {
235 struct L {
236 protected:
237   L(int);
238   // expected-note@-1 2{{declared protected here}}
239 };
240 
241 struct M : L {};
242 
243 struct N {
244   L l;
245 };
246 
247 M m(42);
248 // expected-error@-1 {{base class 'L' has protected constructor}}
249 // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
250 
251 N n(43);
252 // expected-error@-1 {{field of type 'L' has protected constructor}}
253 // beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}}
254 }
255 
256 namespace gh61567 {
257 struct O {
258   int i;
259   int &&j;
260   // expected-note@-1 {{uninitialized reference member is here}}
261   int &&k = 1;
262 };
263 
264 O o1(0, 0, 0); // no-error
265 // beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}
266 // expected-warning@-2 {{temporary whose address is used as value of local variable 'o1' will be destroyed at the end of the full-expression}}
267 // expected-warning@-3 {{temporary whose address is used as value of local variable 'o1' will be destroyed at the end of the full-expression}}
268 
269 O o2(0, 0); // no-error
270 // beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}
271 // expected-warning@-2 {{temporary whose address is used as value of local variable 'o2' will be destroyed at the end of the full-expression}}
272 
273 O o3(0);
274 // expected-error@-1 {{reference member of type 'int &&' uninitialized}}
275 }
276 
277 namespace gh63008 {
278 auto a = new A('a', {1.1});
279 // expected-warning@-1 {{braces around scalar init}}
280 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
281 }
282 
283 
284 namespace GH63278 {
285 struct S {
286   int a = 0;
287   int b {0};
288   auto x = 1; // expected-error {{'auto' not allowed in non-static struct member}}
289   static const auto y = 1;
290 };
291 
292 int test() {
293   // used to crash
294   S a(0, 1);
295   S b(0);
296   S c(0, 0, 1);
297 
298   S d {0, 1};
299   S e {0};
300   S f {0, 0, 1};
301 }
302 
303 }
304 
305 namespace gh63758 {
306   struct S {} s;
307   auto words = (char[])s; // expected-error {{C-style cast from 'struct S' to 'char[]' is not allowed}}
308 };
309 
310 namespace GH63903 {
311   constexpr int f(); // expected-note {{declared here}}
312   struct S {
313     int a = 0, b = f(); // expected-note {{undefined function 'f' cannot be used in a constant expression}}
314   };
315 
316   // Test that errors produced by default members are produced at the location of the initialization
317   constexpr S s(0); // beforecxx20-warning {{aggregate initialization of type 'const S' from a parenthesized list of values is a C++20 extension}} \
318                     // expected-error {{constexpr variable 's' must be initialized by a constant expression}}
319 }
320 
321 namespace gh62863 {
322 
323 int (&&arr)[] = static_cast<int[]>(42);
324 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
325 int (&&arr1)[1] = static_cast<int[]>(42);
326 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
327 int (&&arr2)[2] = static_cast<int[]>(42); // expected-error {{reference to type 'int[2]' could not bind to an rvalue of type 'int[1]'}}
328 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
329 int (&&arr3)[3] = static_cast<int[3]>(42);
330 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}}
331 
332 int (&&arr4)[] = (int[])(42);
333 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
334 int (&&arr5)[1] = (int[])(42);
335 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
336 int (&&arr6)[2] = (int[])(42); // expected-error {{reference to type 'int[2]' could not bind to an rvalue of type 'int[1]'}}
337 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
338 int (&&arr7)[3] = (int[3])(42);
339 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}}
340 
341 }
342 
343 namespace GH92284 {
344 
345 using T = int[1]; T x(42);
346 // beforecxx20-warning@-1 {{aggregate initialization of type 'T' (aka 'int[1]') from a parenthesized list of values is a C++20 extension}}
347 using Ta = int[2]; Ta a(42);
348 // beforecxx20-warning@-1 {{aggregate initialization of type 'Ta' (aka 'int[2]') from a parenthesized list of values is a C++20 extension}}
349 using Tb = int[2]; Tb b(42,43);
350 // beforecxx20-warning@-1 {{aggregate initialization of type 'Tb' (aka 'int[2]') from a parenthesized list of values is a C++20 extension}}
351 using Tc = int[]; Tc c(42);
352 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
353 using Td = int[]; Td d(42,43);
354 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
355 template<typename T, int Sz> using ThroughAlias = T[Sz];
356 ThroughAlias<int, 1> e(42);
357 // beforecxx20-warning@-1 {{aggregate initialization of type 'ThroughAlias<int, 1>' (aka 'int[1]') from a parenthesized list of values is a C++20 extension}}
358 
359 }
360