// RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only // RUN: %clang_cc1 -verify -std=c++20 %s -fsyntax-only -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -verify=expected,beforecxx20 -Wc++20-extensions -std=c++20 %s -fsyntax-only struct A { // expected-note 4{{candidate constructor}} char i; double j; }; struct B { A a; int b[20]; int &&c; }; struct C { // expected-note 5{{candidate constructor}} A a; int b[20]; }; struct D : public C, public A { int a; }; struct E { struct F { // expected-note 2{{candidate constructor}} F(int, int); // expected-note {{candidate constructor}} }; int a; F f; }; int getint(); // expected-note {{declared here}} struct F { int a; int b = getint(); // expected-note {{non-constexpr function 'getint' cannot be used in a constant expression}} }; template struct G { T t1; T t2; }; struct H { virtual void foo() = 0; }; struct I : public H { // expected-note 3{{candidate constructor}} int i, j; void foo() override {} }; struct J { int a; int b[]; // expected-note {{initialized flexible array member 'b' is here}} }; enum K { K0, K1, K2 }; struct L { K k : 1; }; struct M { struct N { private: N(int); // expected-note@-1 {{declared private here}} }; int i; N n; }; union U { int a; char* b; }; template void bar() { T t = 0; A a(CH, 1.1); // OK; C++ paren list constructors are supported in semantic tree transformations. // beforecxx20-warning@-1 2{{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} } template T Construct(Args... args) { return T(args...); // OK; variadic arguments can be used in paren list initializers. // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} } void foo(int n) { // expected-note {{declared here}} A a1(1954, 9, 21); // expected-error@-1 {{excess elements in struct initializer}} A a2(2.1); // expected-warning@-1 {{implicit conversion from 'double' to 'char'}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} A a3(-1.2, 9.8); // expected-warning@-1 {{implicit conversion from 'double' to 'char'}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} A a4 = static_cast(1.1); // expected-warning@-1 {{implicit conversion from 'double' to 'char'}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} A a5 = (A)3.1; // expected-warning@-1 {{implicit conversion from 'double' to 'char'}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} A a6 = A(8.7); // expected-warning@-1 {{implicit conversion from 'double' to 'char'}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} B b1(2022, {7, 8}); // expected-error@-1 {{no viable conversion from 'int' to 'A'}} B b2(A(1), {}, 1); // beforecxx20-warning@-1 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} // beforecxx20-warning@-2 {{aggregate initialization of type 'B' from a parenthesized list of values is a C++20 extension}} C c(A(1), 1, 2, 3, 4); // expected-error@-1 {{array initializer must be an initializer list}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} D d1(1); // expected-error@-1 {{no viable conversion from 'int' to 'C'}} D d2(C(1)); // expected-error@-1 {{no matching conversion for functional-style cast from 'int' to 'C'}} // beforecxx20-warning@-2 {{aggregate initialization of type 'D' from a parenthesized list of values is a C++20 extension}} D d3(C(A(1)), 1); // expected-error@-1 {{no viable conversion from 'int' to 'A'}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} // beforecxx20-warning@-3 {{aggregate initialization of type 'C' from a parenthesized list of values is a C++20 extension}} int arr1[](0, 1, 2, A(1)); // expected-error@-1 {{no viable conversion from 'A' to 'int'}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} int arr2[2](0, 1, 2); // expected-error@-1 {{excess elements in array initializer}} // We should not build paren list initilizations for IK_COPY. int arr3[1] = 1; // expected-error@-1 {{array initializer must be an initializer list}} U u1("abcd"); // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}} U u2(1, "efgh"); // expected-error@-1 {{excess elements in union initializer}} E e1(1); // expected-error@-1 {{no matching constructor for initialization of 'F'}} constexpr F f1(1); // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}} // beforecxx20-warning@-2 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}} constexpr F f2(1, 1); // OK: f2.b is initialized by a constant expression. // beforecxx20-warning@-1 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}} bar(); // beforecxx20-note@-1 {{in instantiation of function template specialization 'bar' requested here}} G g('b', 'b'); // beforecxx20-warning@-1 {{aggregate initialization of type 'G' from a parenthesized list of values is a C++20 extension}} A a7 = Construct('i', 2.2); // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct' requested here}} L l(K::K2); // expected-warning@-1 {{implicit truncation}} // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}} int arr4[](1, 2); // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}} int arr5[2](1, 2); // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}} int arr6[n](1, 2, 3); // expected-warning {{variable length arrays in C++ are a Clang extension}} \ expected-note {{function parameter 'n' with unknown value cannot be used in a constant expression}} \ expected-error {{variable-sized object may not be initialized}} I i(1, 2); // expected-error@-1 {{no matching constructor for initialization of 'I'}} J j(1, {2, 3}); // expected-error@-1 {{initialization of flexible array member is not allowed}} M m(1, 1); // expected-error@-1 {{field of type 'N' has private constructor}} // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}} static_assert(__is_trivially_constructible(A, char, double)); static_assert(__is_trivially_constructible(A, char, int)); static_assert(__is_trivially_constructible(A, char)); static_assert(__is_trivially_constructible(D, C, A, int)); static_assert(__is_trivially_constructible(D, C)); static_assert(__is_trivially_constructible(int[2], int, int)); static_assert(__is_trivially_constructible(int[2], int, double)); static_assert(__is_trivially_constructible(int[2], int)); } namespace gh59675 { struct K { template K(T); virtual ~K(); }; union V { K k; // expected-note@-1 {{default constructor of 'V' is implicitly deleted because field 'k' has no default constructor}} // expected-note@-2 2{{copy constructor of 'V' is implicitly deleted because variant field 'k' has a non-trivial copy constructor}} }; static_assert(!__is_constructible(V, const V&)); static_assert(!__is_constructible(V, V&&)); void bar() { V v1; // expected-error@-1 {{call to implicitly-deleted default constructor of 'V'}} V v2(v1); // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}} V v3((V&&) v1); // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}} } } namespace gh62296 { struct L { protected: L(int); // expected-note@-1 2{{declared protected here}} }; struct M : L {}; struct N { L l; }; M m(42); // expected-error@-1 {{base class 'L' has protected constructor}} // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}} N n(43); // expected-error@-1 {{field of type 'L' has protected constructor}} // beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}} } namespace gh61567 { struct O { int i; int &&j; // expected-note@-1 {{uninitialized reference member is here}} int &&k = 1; }; O o1(0, 0, 0); // no-error // beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}} O o2(0, 0); // no-error // beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}} O o3(0); // expected-error@-1 {{reference member of type 'int &&' uninitialized}} } namespace gh63008 { auto a = new A('a', {1.1}); // expected-warning@-1 {{braces around scalar init}} // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} } namespace GH63278 { struct S { int a = 0; int b {0}; auto x = 1; // expected-error {{'auto' not allowed in non-static struct member}} static const auto y = 1; }; int test() { // used to crash S a(0, 1); S b(0); S c(0, 0, 1); S d {0, 1}; S e {0}; S f {0, 0, 1}; } } namespace gh63758 { struct S {} s; auto words = (char[])s; // expected-error {{C-style cast from 'struct S' to 'char[]' is not allowed}} }; namespace GH63903 { constexpr int f(); // expected-note {{declared here}} struct S { int a = 0, b = f(); // expected-note {{undefined function 'f' cannot be used in a constant expression}} }; // Test that errors produced by default members are produced at the location of the initialization constexpr S s(0); // beforecxx20-warning {{aggregate initialization of type 'const S' from a parenthesized list of values is a C++20 extension}} \ // expected-error {{constexpr variable 's' must be initialized by a constant expression}} }