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 5 6 struct A { // expected-note 4{{candidate constructor}} 7 char i; 8 double j; 9 }; 10 11 struct B { 12 A a; 13 int b[20]; 14 int &&c; 15 }; 16 17 struct C { // expected-note 5{{candidate constructor}} 18 A a; 19 int b[20]; 20 }; 21 22 struct D : public C, public A { 23 int a; 24 }; 25 26 struct E { 27 struct F { // expected-note 2{{candidate constructor}} 28 F(int, int); // expected-note {{candidate constructor}} 29 }; 30 int a; 31 F f; 32 }; 33 34 int getint(); // expected-note {{declared here}} 35 36 struct F { 37 int a; 38 int b = getint(); // expected-note {{non-constexpr function 'getint' cannot be used in a constant expression}} 39 }; 40 41 template <typename T> 42 struct G { 43 T t1; 44 T t2; 45 }; 46 47 struct H { 48 virtual void foo() = 0; 49 }; 50 51 struct I : public H { // expected-note 3{{candidate constructor}} 52 int i, j; 53 void foo() override {} 54 }; 55 56 struct J { 57 int a; 58 int b[]; // expected-note {{initialized flexible array member 'b' is here}} 59 }; 60 61 enum K { K0, K1, K2 }; 62 63 struct L { 64 K k : 1; 65 }; 66 67 struct M { 68 struct N { 69 private: 70 N(int); 71 // expected-note@-1 {{declared private here}} 72 }; 73 int i; 74 N n; 75 }; 76 77 union U { 78 int a; 79 char* b; 80 }; 81 82 template <typename T, char CH> 83 void bar() { 84 T t = 0; 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}} 87 } 88 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}} 93 } 94 95 void foo(int n) { // expected-note {{declared here}} 96 A a1(1954, 9, 21); 97 // expected-error@-1 {{excess elements in struct initializer}} 98 A a2(2.1); 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}} 101 A a3(-1.2, 9.8); 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}} 107 A a5 = (A)3.1; 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}} 110 A a6 = A(8.7); 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}} 113 114 B b1(2022, {7, 8}); 115 // expected-error@-1 {{no viable conversion from 'int' to 'A'}} 116 B b2(A(1), {}, 1); 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}} 119 // expected-warning@-3 {{temporary whose address is used as value of local variable 'b2' will be destroyed at the end of the full-expression}} 120 121 C c(A(1), 1, 2, 3, 4); 122 // expected-error@-1 {{array initializer must be an initializer list}} 123 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} 124 D d1(1); 125 // expected-error@-1 {{no viable conversion from 'int' to 'C'}} 126 D d2(C(1)); 127 // expected-error@-1 {{no matching conversion for functional-style cast from 'int' to 'C'}} 128 // beforecxx20-warning@-2 {{aggregate initialization of type 'D' from a parenthesized list of values is a C++20 extension}} 129 D d3(C(A(1)), 1); 130 // expected-error@-1 {{no viable conversion from 'int' to 'A'}} 131 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} 132 // beforecxx20-warning@-3 {{aggregate initialization of type 'C' from a parenthesized list of values is a C++20 extension}} 133 134 int arr1[](0, 1, 2, A(1)); 135 // expected-error@-1 {{no viable conversion from 'A' to 'int'}} 136 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} 137 138 int arr2[2](0, 1, 2); 139 // expected-error@-1 {{excess elements in array initializer}} 140 141 // We should not build paren list initilizations for IK_COPY. 142 int arr3[1] = 1; 143 // expected-error@-1 {{array initializer must be an initializer list}} 144 145 U u1("abcd"); 146 // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}} 147 U u2(1, "efgh"); 148 // expected-error@-1 {{excess elements in union initializer}} 149 150 E e1(1); 151 // expected-error@-1 {{no matching constructor for initialization of 'F'}} 152 153 constexpr F f1(1); 154 // expected-error@-1 {{constexpr variable 'f1' must be initialized by a constant expression}} 155 // beforecxx20-warning@-2 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}} 156 157 constexpr F f2(1, 1); // OK: f2.b is initialized by a constant expression. 158 // beforecxx20-warning@-1 {{aggregate initialization of type 'const F' from a parenthesized list of values is a C++20 extension}} 159 160 bar<int, 'a'>(); 161 // beforecxx20-note@-1 {{in instantiation of function template specialization 'bar<int, 'a'>' requested here}} 162 163 G<char> g('b', 'b'); 164 // beforecxx20-warning@-1 {{aggregate initialization of type 'G<char>' from a parenthesized list of values is a C++20 extension}} 165 166 A a7 = Construct<A>('i', 2.2); 167 // beforecxx20-note@-1 {{in instantiation of function template specialization 'Construct<A, char, double>' requested here}} 168 169 L l(K::K2); 170 // expected-warning@-1 {{implicit truncation}} 171 // beforecxx20-warning@-2 {{aggregate initialization of type 'L' from a parenthesized list of values is a C++20 extension}} 172 173 int arr4[](1, 2); 174 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}} 175 176 int arr5[2](1, 2); 177 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}} 178 179 int arr6[n](1, 2, 3); // expected-warning {{variable length arrays in C++ are a Clang extension}} \ 180 expected-note {{function parameter 'n' with unknown value cannot be used in a constant expression}} \ 181 expected-error {{variable-sized object may not be initialized}} 182 183 I i(1, 2); 184 // expected-error@-1 {{no matching constructor for initialization of 'I'}} 185 186 J j(1, {2, 3}); 187 // expected-error@-1 {{initialization of flexible array member is not allowed}} 188 189 M m(1, 1); 190 // expected-error@-1 {{field of type 'N' has private constructor}} 191 // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}} 192 193 static_assert(__is_trivially_constructible(A, char, double)); 194 static_assert(__is_trivially_constructible(A, char, int)); 195 static_assert(__is_trivially_constructible(A, char)); 196 197 static_assert(__is_trivially_constructible(D, C, A, int)); 198 static_assert(__is_trivially_constructible(D, C)); 199 200 static_assert(__is_trivially_constructible(int[2], int, int)); 201 static_assert(__is_trivially_constructible(int[2], int, double)); 202 static_assert(__is_trivially_constructible(int[2], int)); 203 } 204 205 namespace gh59675 { 206 struct K { 207 template <typename T> 208 K(T); 209 210 virtual ~K(); 211 }; 212 213 union V { 214 K k; 215 // expected-note@-1 {{default constructor of 'V' is implicitly deleted because field 'k' has no default constructor}} 216 // expected-note@-2 2{{copy constructor of 'V' is implicitly deleted because variant field 'k' has a non-trivial copy constructor}} 217 }; 218 219 static_assert(!__is_constructible(V, const V&)); 220 static_assert(!__is_constructible(V, V&&)); 221 222 void bar() { 223 V v1; 224 // expected-error@-1 {{call to implicitly-deleted default constructor of 'V'}} 225 226 V v2(v1); 227 // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}} 228 229 V v3((V&&) v1); 230 // expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}} 231 } 232 } 233 234 namespace gh62296 { 235 struct L { 236 protected: 237 L(int); 238 // expected-note@-1 2{{declared protected here}} 239 }; 240 241 struct M : L {}; 242 243 struct N { 244 L l; 245 }; 246 247 M m(42); 248 // expected-error@-1 {{base class 'L' has protected constructor}} 249 // beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}} 250 251 N n(43); 252 // expected-error@-1 {{field of type 'L' has protected constructor}} 253 // beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}} 254 } 255 256 namespace gh61567 { 257 struct O { 258 int i; 259 int &&j; 260 // expected-note@-1 {{uninitialized reference member is here}} 261 int &&k = 1; 262 }; 263 264 O o1(0, 0, 0); // no-error 265 // beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}} 266 // expected-warning@-2 {{temporary whose address is used as value of local variable 'o1' will be destroyed at the end of the full-expression}} 267 // expected-warning@-3 {{temporary whose address is used as value of local variable 'o1' will be destroyed at the end of the full-expression}} 268 269 O o2(0, 0); // no-error 270 // beforecxx20-warning@-1 {{aggregate initialization of type 'O' from a parenthesized list of values is a C++20 extension}} 271 // expected-warning@-2 {{temporary whose address is used as value of local variable 'o2' will be destroyed at the end of the full-expression}} 272 273 O o3(0); 274 // expected-error@-1 {{reference member of type 'int &&' uninitialized}} 275 } 276 277 namespace gh63008 { 278 auto a = new A('a', {1.1}); 279 // expected-warning@-1 {{braces around scalar init}} 280 // beforecxx20-warning@-2 {{aggregate initialization of type 'A' from a parenthesized list of values is a C++20 extension}} 281 } 282 283 284 namespace GH63278 { 285 struct S { 286 int a = 0; 287 int b {0}; 288 auto x = 1; // expected-error {{'auto' not allowed in non-static struct member}} 289 static const auto y = 1; 290 }; 291 292 int test() { 293 // used to crash 294 S a(0, 1); 295 S b(0); 296 S c(0, 0, 1); 297 298 S d {0, 1}; 299 S e {0}; 300 S f {0, 0, 1}; 301 } 302 303 } 304 305 namespace gh63758 { 306 struct S {} s; 307 auto words = (char[])s; // expected-error {{C-style cast from 'struct S' to 'char[]' is not allowed}} 308 }; 309 310 namespace GH63903 { 311 constexpr int f(); // expected-note {{declared here}} 312 struct S { 313 int a = 0, b = f(); // expected-note {{undefined function 'f' cannot be used in a constant expression}} 314 }; 315 316 // Test that errors produced by default members are produced at the location of the initialization 317 constexpr S s(0); // beforecxx20-warning {{aggregate initialization of type 'const S' from a parenthesized list of values is a C++20 extension}} \ 318 // expected-error {{constexpr variable 's' must be initialized by a constant expression}} 319 } 320 321 namespace gh62863 { 322 323 int (&&arr)[] = static_cast<int[]>(42); 324 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} 325 int (&&arr1)[1] = static_cast<int[]>(42); 326 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} 327 int (&&arr2)[2] = static_cast<int[]>(42); // expected-error {{reference to type 'int[2]' could not bind to an rvalue of type 'int[1]'}} 328 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} 329 int (&&arr3)[3] = static_cast<int[3]>(42); 330 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}} 331 332 int (&&arr4)[] = (int[])(42); 333 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} 334 int (&&arr5)[1] = (int[])(42); 335 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} 336 int (&&arr6)[2] = (int[])(42); // expected-error {{reference to type 'int[2]' could not bind to an rvalue of type 'int[1]'}} 337 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} 338 int (&&arr7)[3] = (int[3])(42); 339 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[3]' from a parenthesized list of values is a C++20 extension}} 340 341 } 342 343 namespace GH92284 { 344 345 using T = int[1]; T x(42); 346 // beforecxx20-warning@-1 {{aggregate initialization of type 'T' (aka 'int[1]') from a parenthesized list of values is a C++20 extension}} 347 using Ta = int[2]; Ta a(42); 348 // beforecxx20-warning@-1 {{aggregate initialization of type 'Ta' (aka 'int[2]') from a parenthesized list of values is a C++20 extension}} 349 using Tb = int[2]; Tb b(42,43); 350 // beforecxx20-warning@-1 {{aggregate initialization of type 'Tb' (aka 'int[2]') from a parenthesized list of values is a C++20 extension}} 351 using Tc = int[]; Tc c(42); 352 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[1]' from a parenthesized list of values is a C++20 extension}} 353 using Td = int[]; Td d(42,43); 354 // beforecxx20-warning@-1 {{aggregate initialization of type 'int[2]' from a parenthesized list of values is a C++20 extension}} 355 template<typename T, int Sz> using ThroughAlias = T[Sz]; 356 ThroughAlias<int, 1> e(42); 357 // beforecxx20-warning@-1 {{aggregate initialization of type 'ThroughAlias<int, 1>' (aka 'int[1]') from a parenthesized list of values is a C++20 extension}} 358 359 } 360