xref: /llvm-project/clang/test/SemaCXX/paren-list-agg-init.cpp (revision 7417e9d75c9af7dd0d3dad12eebdee84b10b56d7)
1 // RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only
2 // RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only
3 
4 struct A { // expected-note 4{{candidate constructor}}
5   char i;
6   double j;
7 };
8 
9 struct B {
10   A a;
11   int b[20];
12   int &&c; // expected-note {{reference member declared here}}
13 };
14 
15 struct C { // expected-note 5{{candidate constructor}}
16   A a;
17   int b[20];
18 };
19 
20 struct D : public C, public A {
21   int a;
22 };
23 
24 struct E { // expected-note 3{{candidate constructor}}
25   struct F {
26     F(int, int);
27   };
28   int a;
29   F f;
30 };
31 
32 int getint(); // expected-note {{declared here}}
33 
34 struct F {
35   int a;
36   int b = getint(); // expected-note {{non-constexpr function 'getint' cannot be used in a constant expression}}
37 };
38 
39 template <typename T>
40 struct G {
41   T t1;
42   T t2;
43 };
44 
45 struct H {
46   virtual void foo() = 0;
47 };
48 
49 struct I : public H { // expected-note 3{{candidate constructor}}
50   int i, j;
51   void foo() override {}
52 };
53 
54 struct J {
55   int a;
56   int b[]; // expected-note {{initialized flexible array member 'b' is here}}
57 };
58 
59 union U {
60   int a;
61   char* b;
62 };
63 
64 template <typename T, char CH>
65 void bar() {
66   T t = 0;
67   A a(CH, 1.1); // OK; C++ paren list constructors are supported in semantic tree transformations.
68   // beforecxx20-warning@-1 2{{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
69 }
70 
71 template <class T, class... Args>
72 T Construct(Args... args) {
73   return T(args...); // OK; variadic arguments can be used in paren list initializers.
74   // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
75 }
76 
77 void foo() {
78   A a1(1954, 9, 21);
79   // expected-error@-1 {{excess elements in struct initializer}}
80   A a2(2.1);
81   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
82   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
83   A a3(-1.2, 9.8);
84   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
85   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
86   A a4 = static_cast<A>(1.1);
87   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
88   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
89   A a5 = (A)3.1;
90   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
91   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
92   A a6 = A(8.7);
93   // expected-warning@-1 {{implicit conversion from 'double' to 'char'}}
94   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
95 
96   B b1(2022, {7, 8});
97   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
98   B b2(A(1), {}, 1);
99   // expected-error@-1 {{reference member 'c' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
100   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
101   // beforecxx20-warning@-3 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}}
102 
103   C c(A(1), 1, 2, 3, 4);
104   // expected-error@-1 {{array initializer must be an initializer list}}
105   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
106   D d1(1);
107   // expected-error@-1 {{no viable conversion from 'int' to 'C'}}
108   D d2(C(1));
109   // expected-error@-1 {{no matching conversion for functional-style cast from 'int' to 'C'}}
110   // beforecxx20-warning@-2 {{aggregate initialization of type 'D' from a parenthesized list of values is a C++20 extension}}
111   D d3(C(A(1)), 1);
112   // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
113   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
114   // beforecxx20-warning@-3 {{aggregate initialization of type 'C' from a parenthesized list of values is a C++20 extension}}
115 
116   int arr1[](0, 1, 2, A(1));
117   // expected-error@-1 {{no viable conversion from 'A' to 'int'}}
118   // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
119 
120   int arr2[2](0, 1, 2);
121   // expected-error@-1 {{excess elements in array initializer}}
122 
123   // We should not build paren list initilizations for IK_COPY.
124   int arr3[1] = 1;
125   // expected-error@-1 {{array initializer must be an initializer list}}
126 
127   U u1("abcd");
128   // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}
129   U u2(1, "efgh");
130   // expected-error@-1 {{excess elements in union initializer}}
131 
132   E e1(1);
133   // expected-error@-1 {{no matching constructor for initialization of 'E'}}
134 
135   constexpr F f1(1);
136   // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
137   // beforecxx20-warning@-2 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
138 
139   constexpr F f2(1, 1); // OK: f2.b is initialized by a constant expression.
140   // beforecxx20-warning@-1 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
141 
142   bar<int, 'a'>();
143   // beforecxx20-note@-1 {{in instantiation of function template specialization 'bar<int, 'a'>' requested here}}
144 
145   G<char> g('b', 'b');
146   // beforecxx20-warning@-1 {{aggregate initialization of type 'G<char>' from a parenthesized list of values is a C++20 extension}}
147 
148   A a7 = Construct<A>('i', 2.2);
149   // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct<A, char, double>' requested here}}
150 
151   int arr4[](1, 2);
152   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
153 
154   int arr5[2](1, 2);
155   // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
156 
157   I i(1, 2);
158   // expected-error@-1 {{no matching constructor for initialization of 'I'}}
159 
160   J j(1, {2, 3});
161   // expected-error@-1 {{initialization of flexible array member is not allowed}}
162 
163   static_assert(__is_trivially_constructible(A, char, double));
164   static_assert(__is_trivially_constructible(A, char, int));
165   static_assert(__is_trivially_constructible(A, char));
166 
167   static_assert(__is_trivially_constructible(D, C, A, int));
168   static_assert(__is_trivially_constructible(D, C));
169 
170   static_assert(__is_trivially_constructible(int[2], int, int));
171   static_assert(__is_trivially_constructible(int[2], int, double));
172   static_assert(__is_trivially_constructible(int[2], int));
173 }
174 
175 namespace gh59675 {
176 struct K {
177   template <typename T>
178   K(T);
179 
180   virtual ~K();
181 };
182 
183 union V {
184   K k;
185   // expected-note@-1 {{default constructor of 'V' is implicitly deleted because field 'k' has no default constructor}}
186   // expected-note@-2 2{{copy constructor of 'V' is implicitly deleted because variant field 'k' has a non-trivial copy constructor}}
187 };
188 
189 static_assert(!__is_constructible(V, const V&));
190 static_assert(!__is_constructible(V, V&&));
191 
192 void bar() {
193   V v1;
194   // expected-error@-1 {{call to implicitly-deleted default constructor of 'V'}}
195 
196   V v2(v1);
197   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
198 
199   V v3((V&&) v1);
200   // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
201 }
202 }
203 
204 namespace gh62296 {
205 struct L {
206 protected:
207   L(int);
208   // expected-note@-1 2{{declared protected here}}
209 };
210 
211 struct M : L {};
212 
213 struct N {
214   L l;
215 };
216 
217 M m(42);
218 // expected-error@-1 {{base class 'L' has protected constructor}}
219 // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
220 
221 N n(43);
222 // expected-error@-1 {{field of type 'L' has protected constructor}}
223 // beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}}
224 
225 }
226