| // 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 <typename T> |
| 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 <typename T, char CH> |
| 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 <class T, class... Args> |
| 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<A>(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<int, 'a'>(); |
| // beforecxx20-note@-1 {{in instantiation of function template specialization 'bar<int, 'a'>' requested here}} |
| |
| G<char> g('b', 'b'); |
| // beforecxx20-warning@-1 {{aggregate initialization of type 'G<char>' from a parenthesized list of values is a C++20 extension}} |
| |
| A a7 = Construct<A>('i', 2.2); |
| // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct<A, char, double>' 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 <typename T> |
| 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}} |
| } |