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
6 struct A
{ // expected-note 4{{candidate constructor}}
17 struct C
{ // expected-note 5{{candidate constructor}}
22 struct D
: public C
, public A
{
27 struct F
{ // expected-note 2{{candidate constructor}}
28 F(int, int); // expected-note {{candidate constructor}}
34 int getint(); // expected-note {{declared here}}
38 int b
= getint(); // expected-note {{non-constexpr function 'getint' cannot be used in a constant expression}}
48 virtual void foo() = 0;
51 struct I
: public H
{ // expected-note 3{{candidate constructor}}
53 void foo() override
{}
58 int b
[]; // expected-note {{initialized flexible array member 'b' is here}}
61 enum K
{ K0
, K1
, K2
};
71 // expected-note@-1 {{declared private here}}
82 template <typename T
, char CH
>
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}}
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}}
95 void foo(int n
) { // expected-note {{declared here}}
97 // expected-error@-1 {{excess elements in struct initializer}}
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}}
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}}
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}}
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}}
115 // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
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}}
120 C
c(A(1), 1, 2, 3, 4);
121 // expected-error@-1 {{array initializer must be an initializer list}}
122 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
124 // expected-error@-1 {{no viable conversion from 'int' to 'C'}}
126 // expected-error@-1 {{no matching conversion for functional-style cast from 'int' to 'C'}}
127 // beforecxx20-warning@-2 {{aggregate initialization of type 'D' from a parenthesized list of values is a C++20 extension}}
129 // expected-error@-1 {{no viable conversion from 'int' to 'A'}}
130 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
131 // beforecxx20-warning@-3 {{aggregate initialization of type 'C' from a parenthesized list of values is a C++20 extension}}
133 int arr1
[](0, 1, 2, A(1));
134 // expected-error@-1 {{no viable conversion from 'A' to 'int'}}
135 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
137 int arr2
[2](0, 1, 2);
138 // expected-error@-1 {{excess elements in array initializer}}
140 // We should not build paren list initilizations for IK_COPY.
142 // expected-error@-1 {{array initializer must be an initializer list}}
145 // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}
147 // expected-error@-1 {{excess elements in union initializer}}
150 // expected-error@-1 {{no matching constructor for initialization of 'F'}}
153 // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}}
154 // beforecxx20-warning@-2 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
156 constexpr F
f2(1, 1); // OK: f2.b is initialized by a constant expression.
157 // beforecxx20-warning@-1 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}}
160 // beforecxx20-note@-1 {{in instantiation of function template specialization 'bar<int, 'a'>' requested here}}
163 // beforecxx20-warning@-1 {{aggregate initialization of type 'G<char>' from a parenthesized list of values is a C++20 extension}}
165 A a7
= Construct
<A
>('i', 2.2);
166 // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct<A, char, double>' requested here}}
169 // expected-warning@-1 {{implicit truncation}}
170 // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}}
173 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
176 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
178 int arr6
[n
](1, 2, 3); // expected-warning {{variable length arrays in C++ are a Clang extension}} \
179 expected
-note
{{function parameter
'n' with unknown value cannot be used in a constant expression
}} \
180 expected
-error
{{variable
-sized object may
not be initialized
}}
183 // expected-error@-1 {{no matching constructor for initialization of 'I'}}
186 // expected-error@-1 {{initialization of flexible array member is not allowed}}
189 // expected-error@-1 {{field of type 'N' has private constructor}}
190 // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
192 static_assert(__is_trivially_constructible(A
, char, double));
193 static_assert(__is_trivially_constructible(A
, char, int));
194 static_assert(__is_trivially_constructible(A
, char));
196 static_assert(__is_trivially_constructible(D
, C
, A
, int));
197 static_assert(__is_trivially_constructible(D
, C
));
199 static_assert(__is_trivially_constructible(int[2], int, int));
200 static_assert(__is_trivially_constructible(int[2], int, double));
201 static_assert(__is_trivially_constructible(int[2], int));
206 template <typename T
>
214 // expected-note@-1 {{default constructor of 'V' is implicitly deleted because field 'k' has no default constructor}}
215 // expected-note@-2 2{{copy constructor of 'V' is implicitly deleted because variant field 'k' has a non-trivial copy constructor}}
218 static_assert(!__is_constructible(V
, const V
&));
219 static_assert(!__is_constructible(V
, V
&&));
223 // expected-error@-1 {{call to implicitly-deleted default constructor of 'V'}}
226 // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
229 // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
237 // expected-note@-1 2{{declared protected here}}
247 // expected-error@-1 {{base class 'L' has protected constructor}}
248 // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}
251 // expected-error@-1 {{field of type 'L' has protected constructor}}
252 // beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}}
259 // expected-note@-1 {{uninitialized reference member is here}}
263 O
o1(0, 0, 0); // no-error
264 // beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}
266 O
o2(0, 0); // no-error
267 // beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}}
270 // expected-error@-1 {{reference member of type 'int &&' uninitialized}}
274 auto a
= new A('a', {1.1});
275 // expected-warning@-1 {{braces around scalar init}}
276 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}}
284 auto x
= 1; // expected-error {{'auto' not allowed in non-static struct member}}
285 static const auto y
= 1;
303 auto words
= (char[])s
; // expected-error {{C-style cast from 'struct S' to 'char[]' is not allowed}}
307 constexpr int f(); // expected-note {{declared here}}
309 int a
= 0, b
= f(); // expected-note {{undefined function 'f' cannot be used in a constant expression}}
312 // Test that errors produced by default members are produced at the location of the initialization
313 constexpr S
s(0); // beforecxx20-warning {{aggregate initialization of type 'const S' from a parenthesized list of values is a C++20 extension}} \
314 // expected-error {{constexpr variable 's' must be initialized by a constant expression}}
319 int (&&arr
)[] = static_cast<int[]>(42);
320 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
321 int (&&arr1
)[1] = static_cast<int[]>(42);
322 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
323 int (&&arr2
)[2] = static_cast<int[]>(42); // expected-error {{reference to type 'int[2]' could not bind to an rvalue of type 'int[1]'}}
324 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
325 int (&&arr3
)[3] = static_cast<int[3]>(42);
326 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}}
328 int (&&arr4
)[] = (int[])(42);
329 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
330 int (&&arr5
)[1] = (int[])(42);
331 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
332 int (&&arr6
)[2] = (int[])(42); // expected-error {{reference to type 'int[2]' could not bind to an rvalue of type 'int[1]'}}
333 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
334 int (&&arr7
)[3] = (int[3])(42);
335 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}}
341 using T
= int[1]; T
x(42);
342 // beforecxx20-warning@-1 {{aggregate initialization of type 'T' (aka 'int[1]') from a parenthesized list of values is a C++20 extension}}
343 using Ta
= int[2]; Ta
a(42);
344 // beforecxx20-warning@-1 {{aggregate initialization of type 'Ta' (aka 'int[2]') from a parenthesized list of values is a C++20 extension}}
345 using Tb
= int[2]; Tb
b(42,43);
346 // beforecxx20-warning@-1 {{aggregate initialization of type 'Tb' (aka 'int[2]') from a parenthesized list of values is a C++20 extension}}
347 using Tc
= int[]; Tc
c(42);
348 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}}
349 using Td
= int[]; Td
d(42,43);
350 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}}
351 template<typename T
, int Sz
> using ThroughAlias
= T
[Sz
];
352 ThroughAlias
<int, 1> e(42);
353 // beforecxx20-warning@-1 {{aggregate initialization of type 'ThroughAlias<int, 1>' (aka 'int[1]') from a parenthesized list of values is a C++20 extension}}