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