1 // RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wno-mismatched-new-delete 2 3 #include "Inputs/std-compare.h" 4 5 namespace std { 6 struct type_info; 7 struct destroying_delete_t { 8 explicit destroying_delete_t() = default; 9 } inline constexpr destroying_delete{}; 10 struct nothrow_t { 11 explicit nothrow_t() = default; 12 } inline constexpr nothrow{}; 13 using size_t = decltype(sizeof(0)); 14 enum class align_val_t : size_t {}; 15 }; 16 17 [[nodiscard]] void *operator new(std::size_t, const std::nothrow_t&) noexcept; 18 [[nodiscard]] void *operator new(std::size_t, std::align_val_t, const std::nothrow_t&) noexcept; 19 [[nodiscard]] void *operator new[](std::size_t, const std::nothrow_t&) noexcept; 20 [[nodiscard]] void *operator new[](std::size_t, std::align_val_t, const std::nothrow_t&) noexcept; 21 [[nodiscard]] void *operator new[](std::size_t, std::align_val_t); 22 void operator delete(void*, const std::nothrow_t&) noexcept; 23 void operator delete(void*, std::align_val_t, const std::nothrow_t&) noexcept; 24 void operator delete[](void*, const std::nothrow_t&) noexcept; 25 void operator delete[](void*, std::align_val_t, const std::nothrow_t&) noexcept; 26 27 // Helper to print out values for debugging. 28 constexpr void not_defined(); 29 template<typename T> constexpr void print(T) { not_defined(); } 30 31 namespace ThreeWayComparison { 32 struct A { 33 int n; 34 constexpr friend int operator<=>(const A &a, const A &b) { 35 return a.n < b.n ? -1 : a.n > b.n ? 1 : 0; 36 } 37 }; 38 static_assert(A{1} <=> A{2} < 0); 39 static_assert(A{2} <=> A{1} > 0); 40 static_assert(A{2} <=> A{2} == 0); 41 42 static_assert(1 <=> 2 < 0); 43 static_assert(2 <=> 1 > 0); 44 static_assert(1 <=> 1 == 0); 45 constexpr int k = (1 <=> 1, 0); 46 // expected-warning@-1 {{three-way comparison result unused}} 47 48 static_assert(std::strong_ordering::equal == 0); 49 50 constexpr void f() { 51 void(1 <=> 1); 52 } 53 54 struct MemPtr { 55 void foo() {} 56 void bar() {} 57 int data; 58 int data2; 59 long data3; 60 }; 61 62 struct MemPtr2 { 63 void foo() {} 64 void bar() {} 65 int data; 66 int data2; 67 long data3; 68 }; 69 using MemPtrT = void (MemPtr::*)(); 70 71 using FnPtrT = void (*)(); 72 73 void FnPtr1() {} 74 void FnPtr2() {} 75 76 #define CHECK(...) ((__VA_ARGS__) ? void() : throw "error") 77 #define CHECK_TYPE(...) static_assert(__is_same(__VA_ARGS__)); 78 79 constexpr bool test_constexpr_success = [] { 80 { 81 auto &EQ = std::strong_ordering::equal; 82 auto &LESS = std::strong_ordering::less; 83 auto &GREATER = std::strong_ordering::greater; 84 using SO = std::strong_ordering; 85 auto eq = (42 <=> 42); 86 CHECK_TYPE(decltype(eq), SO); 87 CHECK(eq.test_eq(EQ)); 88 89 auto less = (-1 <=> 0); 90 CHECK_TYPE(decltype(less), SO); 91 CHECK(less.test_eq(LESS)); 92 93 auto greater = (42l <=> 1u); 94 CHECK_TYPE(decltype(greater), SO); 95 CHECK(greater.test_eq(GREATER)); 96 } 97 { 98 using PO = std::partial_ordering; 99 auto EQUIV = PO::equivalent; 100 auto LESS = PO::less; 101 auto GREATER = PO::greater; 102 103 auto eq = (42.0 <=> 42.0); 104 CHECK_TYPE(decltype(eq), PO); 105 CHECK(eq.test_eq(EQUIV)); 106 107 auto less = (39.0 <=> 42.0); 108 CHECK_TYPE(decltype(less), PO); 109 CHECK(less.test_eq(LESS)); 110 111 auto greater = (-10.123 <=> -101.1); 112 CHECK_TYPE(decltype(greater), PO); 113 CHECK(greater.test_eq(GREATER)); 114 } 115 116 return true; 117 }(); 118 119 int dummy = 42; 120 int dummy2 = 101; 121 constexpr bool tc9 = (&dummy <=> &dummy2) != 0; // expected-error {{constant expression}} expected-note {{unspecified}} 122 123 template <class T, class R, class I> 124 constexpr T makeComplex(R r, I i) { 125 T res{r, i}; 126 return res; 127 }; 128 } // namespace ThreeWayComparison 129 130 constexpr bool for_range_init() { 131 int k = 0; 132 for (int arr[3] = {1, 2, 3}; int n : arr) k += n; 133 return k == 6; 134 } 135 static_assert(for_range_init()); 136 137 namespace Virtual { 138 struct NonZeroOffset { int padding = 123; }; 139 140 constexpr void assert(bool b) { if (!b) throw 0; } 141 142 // Ensure that we pick the right final overrider during construction. 143 struct A { 144 virtual constexpr char f() const { return 'A'; } 145 char a = f(); 146 constexpr ~A() { assert(f() == 'A'); } 147 }; 148 struct NoOverrideA : A {}; 149 struct B : NonZeroOffset, NoOverrideA { 150 virtual constexpr char f() const { return 'B'; } 151 char b = f(); 152 constexpr ~B() { assert(f() == 'B'); } 153 }; 154 struct NoOverrideB : B {}; 155 struct C : NonZeroOffset, A { 156 virtual constexpr char f() const { return 'C'; } 157 A *pba; 158 char c = ((A*)this)->f(); 159 char ba = pba->f(); 160 constexpr C(A *pba) : pba(pba) {} 161 constexpr ~C() { assert(f() == 'C'); } 162 }; 163 struct D : NonZeroOffset, NoOverrideB, C { // expected-warning {{inaccessible}} 164 virtual constexpr char f() const { return 'D'; } 165 char d = f(); 166 constexpr D() : C((B*)this) {} 167 constexpr ~D() { assert(f() == 'D'); } 168 }; 169 constexpr int n = (D(), 0); 170 constexpr D d; 171 static_assert(((B&)d).a == 'A'); 172 static_assert(((C&)d).a == 'A'); 173 static_assert(d.b == 'B'); 174 static_assert(d.c == 'C'); 175 // During the construction of C, the dynamic type of B's A is B. 176 static_assert(d.ba == 'B'); 177 static_assert(d.d == 'D'); 178 static_assert(d.f() == 'D'); 179 constexpr const A &a = (B&)d; 180 constexpr const B &b = d; 181 static_assert(a.f() == 'D'); 182 static_assert(b.f() == 'D'); 183 184 // FIXME: It is unclear whether this should be permitted. 185 D d_not_constexpr; 186 static_assert(d_not_constexpr.f() == 'D'); // expected-error {{constant expression}} expected-note {{virtual function called on object 'd_not_constexpr' whose dynamic type is not constant}} 187 188 // Check that we apply a proper adjustment for a covariant return type. 189 struct Covariant1 { 190 D d; 191 virtual const A *f() const; 192 }; 193 template<typename T> 194 struct Covariant2 : Covariant1 { 195 virtual const T *f() const; 196 }; 197 template<typename T> 198 struct Covariant3 : Covariant2<T> { 199 constexpr virtual const D *f() const { return &this->d; } 200 }; 201 202 constexpr Covariant3<B> cb; 203 constexpr Covariant3<C> cc; 204 205 constexpr const Covariant1 *cb1 = &cb; 206 constexpr const Covariant2<B> *cb2 = &cb; 207 static_assert(cb1->f()->a == 'A'); 208 static_assert(cb1->f() == (B*)&cb.d); 209 static_assert(cb1->f()->f() == 'D'); 210 static_assert(cb2->f()->b == 'B'); 211 static_assert(cb2->f() == &cb.d); 212 static_assert(cb2->f()->f() == 'D'); 213 214 constexpr const Covariant1 *cc1 = &cc; 215 constexpr const Covariant2<C> *cc2 = &cc; 216 static_assert(cc1->f()->a == 'A'); 217 static_assert(cc1->f() == (C*)&cc.d); 218 static_assert(cc1->f()->f() == 'D'); 219 static_assert(cc2->f()->c == 'C'); 220 static_assert(cc2->f() == &cc.d); 221 static_assert(cc2->f()->f() == 'D'); 222 223 static_assert(cb.f()->d == 'D'); 224 static_assert(cc.f()->d == 'D'); 225 226 struct Abstract { 227 constexpr virtual void f() = 0; // expected-note {{declared here}} 228 constexpr Abstract() { do_it(); } // expected-note {{in call to}} 229 constexpr void do_it() { f(); } // expected-note {{pure virtual function 'Virtual::Abstract::f' called}} 230 }; 231 struct PureVirtualCall : Abstract { void f(); }; // expected-note {{in call to 'Abstract}} 232 constexpr PureVirtualCall pure_virtual_call; // expected-error {{constant expression}} expected-note {{in call to 'PureVirtualCall}} 233 } 234 235 namespace DynamicCast { 236 struct A2 { virtual void a2(); }; 237 struct A : A2 { virtual void a(); }; 238 struct B : A {}; 239 struct C2 { virtual void c2(); }; 240 struct C : A, C2 { A *c = dynamic_cast<A*>(static_cast<C2*>(this)); }; 241 struct D { virtual void d(); }; 242 struct E { virtual void e(); }; 243 struct F : B, C, D, private E { void *f = dynamic_cast<void*>(static_cast<D*>(this)); }; 244 struct Padding { virtual void padding(); }; 245 struct G : Padding, F {}; 246 247 constexpr G g; 248 249 // During construction of C, A is unambiguous subobject of dynamic type C. 250 static_assert(g.c == (C*)&g); 251 // ... but in the complete object, the same is not true, so the runtime fails. 252 static_assert(dynamic_cast<const A*>(static_cast<const C2*>(&g)) == nullptr); 253 254 // dynamic_cast<void*> produces a pointer to the object of the dynamic type. 255 static_assert(g.f == (void*)(F*)&g); 256 static_assert(dynamic_cast<const void*>(static_cast<const D*>(&g)) == &g); 257 258 // expected-note@+1 {{reference dynamic_cast failed: 'A' is an ambiguous base class of dynamic type 'DynamicCast::G' of operand}} 259 constexpr int d_a = (dynamic_cast<const A&>(static_cast<const D&>(g)), 0); // expected-error {{}} 260 261 // Can navigate from A2 to its A... 262 static_assert(&dynamic_cast<A&>((A2&)(B&)g) == &(A&)(B&)g); 263 // ... and from B to its A ... 264 static_assert(&dynamic_cast<A&>((B&)g) == &(A&)(B&)g); 265 // ... but not from D. 266 // expected-note@+1 {{reference dynamic_cast failed: 'A' is an ambiguous base class of dynamic type 'DynamicCast::G' of operand}} 267 static_assert(&dynamic_cast<A&>((D&)g) == &(A&)(B&)g); // expected-error {{}} 268 269 // Can cast from A2 to sibling class D. 270 static_assert(&dynamic_cast<D&>((A2&)(B&)g) == &(D&)g); 271 272 // Cannot cast from private base E to derived class F. 273 // expected-note@+1 {{reference dynamic_cast failed: static type 'DynamicCast::E' of operand is a non-public base class of dynamic type 'DynamicCast::G'}} 274 constexpr int e_f = (dynamic_cast<F&>((E&)g), 0); // expected-error {{}} 275 276 // Cannot cast from B to private sibling E. 277 // expected-note@+1 {{reference dynamic_cast failed: 'E' is a non-public base class of dynamic type 'DynamicCast::G' of operand}} 278 constexpr int b_e = (dynamic_cast<E&>((B&)g), 0); // expected-error {{}} 279 280 struct Unrelated { virtual void unrelated(); }; 281 // expected-note@+1 {{reference dynamic_cast failed: dynamic type 'DynamicCast::G' of operand does not have a base class of type 'Unrelated'}} 282 constexpr int b_unrelated = (dynamic_cast<Unrelated&>((B&)g), 0); // expected-error {{}} 283 // expected-note@+1 {{reference dynamic_cast failed: dynamic type 'DynamicCast::G' of operand does not have a base class of type 'Unrelated'}} 284 constexpr int e_unrelated = (dynamic_cast<Unrelated&>((E&)g), 0); // expected-error {{}} 285 } 286 287 namespace TypeId { 288 struct A { 289 const std::type_info &ti = typeid(*this); 290 }; 291 struct A2 : A {}; 292 static_assert(&A().ti == &typeid(A)); 293 static_assert(&typeid((A2())) == &typeid(A2)); 294 extern A2 extern_a2; 295 static_assert(&typeid(extern_a2) == &typeid(A2)); 296 297 constexpr A2 a2; 298 constexpr const A &a1 = a2; 299 static_assert(&typeid(a1) == &typeid(A)); 300 301 struct B { 302 virtual void f(); 303 const std::type_info &ti1 = typeid(*this); 304 }; 305 struct B2 : B { 306 const std::type_info &ti2 = typeid(*this); 307 }; 308 static_assert(&B2().ti1 == &typeid(B)); 309 static_assert(&B2().ti2 == &typeid(B2)); 310 extern B2 extern_b2; 311 static_assert(&typeid(extern_b2) == &typeid(B2)); 312 313 constexpr B2 b2; 314 constexpr const B &b1 = b2; 315 static_assert(&typeid(b1) == &typeid(B2)); 316 317 constexpr bool side_effects() { 318 // Not polymorphic nor a glvalue. 319 bool OK = true; 320 (void)typeid(OK = false, A2()); // expected-warning {{has no effect}} 321 if (!OK) return false; 322 323 // Not polymorphic. 324 A2 a2; 325 (void)typeid(OK = false, a2); // expected-warning {{has no effect}} 326 if (!OK) return false; 327 328 // Not a glvalue. 329 (void)typeid(OK = false, B2()); // expected-warning {{has no effect}} 330 if (!OK) return false; 331 332 // Polymorphic glvalue: operand evaluated. 333 OK = false; 334 B2 b2; 335 (void)typeid(OK = true, b2); // expected-warning {{will be evaluated}} 336 return OK; 337 } 338 static_assert(side_effects()); 339 } 340 341 namespace Union { 342 struct Base { 343 int y; // expected-note 2{{here}} 344 }; 345 struct A : Base { 346 int x; 347 int arr[3]; 348 union { int p, q; }; 349 }; 350 union B { 351 A a; 352 int b; 353 }; 354 constexpr int read_wrong_member() { // expected-error {{never produces a constant}} 355 B b = {.b = 1}; 356 return b.a.x; // expected-note {{read of member 'a' of union with active member 'b'}} 357 } 358 constexpr int change_member() { 359 B b = {.b = 1}; 360 b.a.x = 1; 361 return b.a.x; 362 } 363 static_assert(change_member() == 1); 364 constexpr int change_member_then_read_wrong_member() { // expected-error {{never produces a constant}} 365 B b = {.b = 1}; 366 b.a.x = 1; 367 return b.b; // expected-note {{read of member 'b' of union with active member 'a'}} 368 } 369 constexpr int read_wrong_member_indirect() { // expected-error {{never produces a constant}} 370 B b = {.b = 1}; 371 int *p = &b.a.y; 372 return *p; // expected-note {{read of member 'a' of union with active member 'b'}} 373 } 374 constexpr int read_uninitialized() { 375 B b = {.b = 1}; 376 int *p = &b.a.y; 377 b.a.x = 1; 378 return *p; // expected-note {{read of uninitialized object}} 379 } 380 static_assert(read_uninitialized() == 0); // expected-error {{constant}} expected-note {{in call}} 381 constexpr void write_wrong_member_indirect() { // expected-error {{never produces a constant}} 382 B b = {.b = 1}; 383 int *p = &b.a.y; 384 *p = 1; // expected-note {{assignment to member 'a' of union with active member 'b'}} 385 } 386 constexpr int write_uninitialized() { 387 B b = {.b = 1}; 388 int *p = &b.a.y; 389 b.a.x = 1; 390 *p = 1; 391 return *p; 392 } 393 static_assert(write_uninitialized() == 1); 394 constexpr int change_member_indirectly() { 395 B b = {.b = 1}; 396 b.a.arr[1] = 1; 397 int &r = b.a.y; 398 r = 123; 399 400 b.b = 2; 401 b.a.y = 3; 402 b.a.arr[2] = 4; 403 return b.a.arr[2]; 404 } 405 static_assert(change_member_indirectly() == 4); 406 constexpr B return_uninit() { 407 B b = {.b = 1}; 408 b.a.x = 2; 409 return b; 410 } 411 constexpr B uninit = return_uninit(); // expected-error {{constant expression}} expected-note {{subobject 'y' is not initialized}} 412 static_assert(return_uninit().a.x == 2); 413 constexpr A return_uninit_struct() { 414 B b = {.b = 1}; 415 b.a.x = 2; 416 return b.a; // expected-note {{in call to 'A(b.a)'}} expected-note {{subobject 'y' is not initialized}} 417 } 418 // Note that this is rejected even though return_uninit() is accepted, and 419 // return_uninit() copies the same stuff wrapped in a union. 420 // 421 // Copying a B involves copying the object representation of the union, but 422 // copying an A invokes a copy constructor that copies the object 423 // elementwise, and reading from b.a.y is undefined. 424 static_assert(return_uninit_struct().x == 2); // expected-error {{constant expression}} expected-note {{in call}} 425 constexpr B return_init_all() { 426 B b = {.b = 1}; 427 b.a.x = 2; 428 b.a.y = 3; 429 b.a.arr[0] = 4; 430 b.a.arr[1] = 5; 431 b.a.arr[2] = 6; 432 return b; 433 } 434 static_assert(return_init_all().a.x == 2); 435 static_assert(return_init_all().a.y == 3); 436 static_assert(return_init_all().a.arr[0] == 4); 437 static_assert(return_init_all().a.arr[1] == 5); 438 static_assert(return_init_all().a.arr[2] == 6); 439 static_assert(return_init_all().a.p == 7); // expected-error {{}} expected-note {{read of member 'p' of union with no active member}} 440 static_assert(return_init_all().a.q == 8); // expected-error {{}} expected-note {{read of member 'q' of union with no active member}} 441 constexpr B init_all = return_init_all(); 442 443 constexpr bool test_no_member_change = []{ 444 union U { char dummy = {}; }; 445 U u1; 446 U u2; 447 u1 = u2; 448 return true; 449 }(); 450 451 struct S1 { 452 int n; 453 }; 454 struct S2 : S1 {}; 455 struct S3 : S2 {}; 456 void f() { 457 S3 s; 458 s.n = 0; 459 } 460 461 union ref_member_1 { 462 int a; 463 int b; 464 }; 465 struct ref_member_2 { 466 ref_member_1 &&r; 467 }; 468 union ref_member_3 { 469 ref_member_2 a, b; 470 }; 471 constexpr int ref_member_test_1() { 472 ref_member_3 r = {.a = {.r = {.a = 1}}}; 473 r.a.r.b = 2; 474 return r.a.r.b; 475 } 476 static_assert(ref_member_test_1() == 2); 477 constexpr int ref_member_test_2() { // expected-error {{never produces a constant}} 478 ref_member_3 r = {.a = {.r = {.a = 1}}}; 479 // FIXME: This note isn't great. The 'read' here is reading the referent of the reference. 480 r.b.r.b = 2; // expected-note {{read of member 'b' of union with active member 'a'}} 481 return r.b.r.b; 482 } 483 484 namespace PR43762 { 485 struct A { int x = 1; constexpr int f() { return 1; } }; 486 struct B : A { int y = 1; constexpr int g() { return 2; } }; 487 struct C { 488 int x; 489 constexpr virtual int f() = 0; 490 }; 491 struct D : C { 492 int y; 493 constexpr virtual int f() override { return 3; } 494 }; 495 496 union U { 497 int n; 498 B b; 499 D d; 500 }; 501 502 constexpr int test(int which) { 503 U u{.n = 5}; 504 switch (which) { 505 case 0: 506 u.b.x = 10; // expected-note {{active member 'n'}} 507 return u.b.f(); 508 case 1: 509 u.b.y = 10; // expected-note {{active member 'n'}} 510 return u.b.g(); 511 case 2: 512 u.d.x = 10; // expected-note {{active member 'n'}} 513 return u.d.f(); 514 case 3: 515 u.d.y = 10; // expected-note {{active member 'n'}} 516 return u.d.f(); 517 } 518 } 519 520 static_assert(test(0)); // expected-error {{}} expected-note {{in call}} 521 static_assert(test(1)); // expected-error {{}} expected-note {{in call}} 522 static_assert(test(2)); // expected-error {{}} expected-note {{in call}} 523 static_assert(test(3)); // expected-error {{}} expected-note {{in call}} 524 } 525 } 526 527 namespace TwosComplementShifts { 528 using uint32 = __UINT32_TYPE__; 529 using int32 = __INT32_TYPE__; 530 static_assert(uint32(int32(0x1234) << 16) == 0x12340000); 531 static_assert(uint32(int32(0x1234) << 19) == 0x91a00000); 532 static_assert(uint32(int32(0x1234) << 20) == 0x23400000); 533 static_assert(uint32(int32(0x1234) << 24) == 0x34000000); 534 static_assert(uint32(int32(-1) << 31) == 0x80000000); 535 536 static_assert(-1 >> 1 == -1); 537 static_assert(-1 >> 31 == -1); 538 static_assert(-2 >> 1 == -1); 539 static_assert(-3 >> 1 == -2); 540 static_assert(-4 >> 1 == -2); 541 } 542 543 namespace Uninit { 544 constexpr int f(bool init) { 545 int a; 546 if (init) 547 a = 1; 548 return a; // expected-note {{read of uninitialized object}} 549 } 550 static_assert(f(true) == 1); 551 static_assert(f(false) == 1); // expected-error {{constant expression}} expected-note {{in call}} 552 553 struct X { 554 int n; // expected-note {{declared here}} 555 constexpr X(bool init) { 556 if (init) n = 123; 557 } 558 }; 559 constinit X x1(true); 560 constinit X x2(false); // expected-error {{constant initializer}} expected-note {{constinit}} expected-note {{subobject 'n' is not initialized}} 561 562 struct Y { 563 struct Z { int n; }; // expected-note {{here}} 564 Z z1; 565 Z z2; 566 Z z3; 567 // OK: the lifetime of z1 (and its members) start before the initializer of 568 // z2 runs. 569 constexpr Y() : z2{ (z1.n = 1, z1.n + 1) } { z3.n = 3; } 570 // Not OK: z3 is not in its lifetime when the initializer of z2 runs. 571 constexpr Y(int) : z2{ 572 (z3.n = 1, // expected-note {{assignment to object outside its lifetime}} 573 z3.n + 1) // expected-warning {{uninitialized}} 574 } { z1.n = 3; } 575 constexpr Y(int, int) : z2{} {} 576 }; 577 // FIXME: This is working around clang not implementing DR2026. With that 578 // fixed, we should be able to test this without the injected copy. 579 constexpr Y copy(Y y) { return y; } // expected-note {{in call to 'Y(y)'}} expected-note {{subobject 'n' is not initialized}} 580 constexpr Y y1 = copy(Y()); 581 static_assert(y1.z1.n == 1 && y1.z2.n == 2 && y1.z3.n == 3); 582 583 constexpr Y y2 = copy(Y(0)); // expected-error {{constant expression}} expected-note {{in call}} 584 585 static_assert(Y(0,0).z2.n == 0); 586 static_assert(Y(0,0).z1.n == 0); // expected-error {{constant expression}} expected-note {{read of uninitialized object}} 587 static_assert(Y(0,0).z3.n == 0); // expected-error {{constant expression}} expected-note {{read of uninitialized object}} 588 589 static_assert(copy(Y(0,0)).z2.n == 0); // expected-error {{constant expression}} expected-note {{in call}} 590 591 constexpr unsigned char not_even_unsigned_char() { 592 unsigned char c; 593 return c; // expected-note {{read of uninitialized object}} 594 } 595 constexpr unsigned char x = not_even_unsigned_char(); // expected-error {{constant expression}} expected-note {{in call}} 596 597 constexpr int switch_var(int n) { 598 switch (n) { 599 case 1: 600 int a; 601 a = n; 602 return a; 603 604 case 2: 605 a = n; 606 return a; 607 } 608 } 609 constexpr int s1 = switch_var(1); 610 constexpr int s2 = switch_var(2); 611 static_assert(s1 == 1 && s2 == 2); 612 613 constexpr bool switch_into_init_stmt() { 614 switch (1) { 615 if (int n; false) { 616 for (int m; false;) { 617 case 1: 618 n = m = 1; 619 return n == 1 && m == 1; 620 } 621 } 622 } 623 } 624 static_assert(switch_into_init_stmt()); 625 } 626 627 namespace dtor { 628 void lifetime_extension() { 629 struct X { constexpr ~X() {} }; 630 X &&a = X(); 631 } 632 633 template<typename T> constexpr T &&ref(T &&t) { return (T&&)t; } 634 635 struct Buf { 636 char buf[64]; 637 int n = 0; 638 constexpr void operator+=(char c) { buf[n++] = c; } 639 constexpr bool operator==(const char *str) const { 640 return str[n] == 0 && __builtin_memcmp(str, buf, n) == 0; 641 } 642 constexpr bool operator!=(const char *str) const { return !operator==(str); } 643 }; 644 645 struct A { 646 constexpr A(Buf &buf, char c) : buf(buf), c(c) { buf += c; } 647 constexpr ~A() { buf += c; } 648 constexpr operator bool() const { return true; } 649 Buf &buf; 650 char c; 651 }; 652 653 constexpr bool dtor_calls_dtor() { 654 union U { 655 constexpr U(Buf &buf) : u(buf, 'u') { buf += 'U'; } 656 constexpr ~U() { u.buf += 'U'; } 657 A u, v; 658 }; 659 660 struct B : A { 661 A c, &&d, e; 662 union { 663 A f; 664 }; 665 U u; 666 constexpr B(Buf &buf) 667 : A(buf, 'a'), c(buf, 'c'), d(ref(A(buf, 'd'))), e(A(buf, 'e')), f(buf, 'f'), u(buf) { 668 buf += 'b'; 669 } 670 constexpr ~B() { 671 buf += 'b'; 672 } 673 }; 674 675 Buf buf; 676 { 677 B b(buf); 678 if (buf != "acddefuUb") 679 return false; 680 } 681 if (buf != "acddefuUbbUeca") 682 return false; 683 return true; 684 } 685 static_assert(dtor_calls_dtor()); 686 687 constexpr void abnormal_termination(Buf &buf) { 688 struct Indestructible { 689 constexpr ~Indestructible(); // not defined 690 }; 691 692 A a(buf, 'a'); 693 A(buf, 'b'); 694 int n = 0; 695 for (A &&c = A(buf, 'c'); A d = A(buf, 'd'); A(buf, 'e')) { 696 switch (A f(buf, 'f'); A g = A(buf, 'g')) { // expected-warning {{boolean}} 697 case false: { 698 A x(buf, 'x'); 699 } 700 701 case true: { 702 A h(buf, 'h'); 703 switch (n++) { 704 case 0: 705 break; 706 case 1: 707 continue; 708 case 2: 709 return; 710 } 711 break; 712 } 713 714 default: 715 Indestructible indest; 716 } 717 718 A j = (A(buf, 'i'), A(buf, 'j')); 719 } 720 } 721 722 constexpr bool check_abnormal_termination() { 723 Buf buf = {}; 724 abnormal_termination(buf); 725 return buf == 726 "abbc" 727 "dfgh" /*break*/ "hgfijijeed" 728 "dfgh" /*continue*/ "hgfeed" 729 "dfgh" /*return*/ "hgfd" 730 "ca"; 731 } 732 static_assert(check_abnormal_termination()); 733 734 constexpr bool run_dtors_on_array_filler() { 735 struct S { 736 int times_destroyed = 0; 737 constexpr ~S() { if (++times_destroyed != 1) throw "oops"; } 738 }; 739 S s[3]; 740 return true; 741 } 742 static_assert(run_dtors_on_array_filler()); 743 744 // Ensure that we can handle temporary cleanups for array temporaries. 745 struct ArrElem { constexpr ~ArrElem() {} }; 746 using Arr = ArrElem[3]; 747 static_assert(((void)Arr{}, true)); 748 } 749 750 namespace dynamic_alloc { 751 constexpr int *p = // expected-error {{constant}} expected-note {{pointer to heap-allocated object is not a constant expression}} 752 new int; // expected-note {{heap allocation performed here}} 753 754 constexpr int f(int n) { 755 int *p = new int[n]; 756 for (int i = 0; i != n; ++i) { 757 p[i] = i; 758 } 759 int k = 0; 760 for (int i = 0; i != n; ++i) { 761 k += p[i]; 762 } 763 delete[] p; 764 return k; 765 } 766 static_assert(f(123) == 123 * 122 / 2); 767 768 constexpr bool nvdtor() { // expected-error {{never produces a constant expression}} 769 struct S { 770 constexpr ~S() {} 771 }; 772 struct T : S {}; 773 delete (S*)new T; // expected-note {{delete of object with dynamic type 'T' through pointer to base class type 'S' with non-virtual destructor}} 774 return true; 775 } 776 777 constexpr int vdtor_1() { 778 int a; 779 struct S { 780 constexpr S(int *p) : p(p) {} 781 constexpr virtual ~S() { *p = 1; } 782 int *p; 783 }; 784 struct T : S { 785 // implicit destructor defined eagerly because it is constexpr and virtual 786 using S::S; 787 }; 788 delete (S*)new T(&a); 789 return a; 790 } 791 static_assert(vdtor_1() == 1); 792 793 constexpr int vdtor_2() { 794 int a = 0; 795 struct S { constexpr virtual ~S() {} }; 796 struct T : S { 797 constexpr T(int *p) : p(p) {} 798 constexpr ~T() { ++*p; } 799 int *p; 800 }; 801 S *p = new T{&a}; 802 delete p; 803 return a; 804 } 805 static_assert(vdtor_2() == 1); 806 807 constexpr int vdtor_3(int mode) { 808 int a = 0; 809 struct S { constexpr virtual ~S() {} }; 810 struct T : S { 811 constexpr T(int *p) : p(p) {} 812 constexpr ~T() { ++*p; } 813 int *p; 814 }; 815 S *p = new T[3]{&a, &a, &a}; // expected-note 2{{heap allocation}} 816 switch (mode) { 817 case 0: 818 delete p; // expected-note {{non-array delete used to delete pointer to array object of type 'T[3]'}} 819 break; 820 case 1: 821 // FIXME: This diagnosic isn't great; we should mention the cast to S* 822 // somewhere in here. 823 delete[] p; // expected-note {{delete of pointer to subobject '&{*new T[3]#0}[0]'}} 824 break; 825 case 2: 826 delete (T*)p; // expected-note {{non-array delete used to delete pointer to array object of type 'T[3]'}} 827 break; 828 case 3: 829 delete[] (T*)p; 830 break; 831 } 832 return a; 833 } 834 static_assert(vdtor_3(0) == 3); // expected-error {{}} expected-note {{in call}} 835 static_assert(vdtor_3(1) == 3); // expected-error {{}} expected-note {{in call}} 836 static_assert(vdtor_3(2) == 3); // expected-error {{}} expected-note {{in call}} 837 static_assert(vdtor_3(3) == 3); 838 839 constexpr void delete_mismatch() { // expected-error {{never produces a constant expression}} 840 delete[] // expected-note {{array delete used to delete pointer to non-array object of type 'int'}} 841 new int; // expected-note {{allocation}} 842 } 843 844 template<typename T> 845 constexpr T dynarray(int elems, int i) { 846 T *p; 847 if constexpr (sizeof(T) == 1) 848 p = new T[elems]{"fox"}; // expected-note {{evaluated array bound 3 is too small to hold 4 explicitly initialized elements}} 849 else 850 p = new T[elems]{1, 2, 3}; // expected-note {{evaluated array bound 2 is too small to hold 3 explicitly initialized elements}} 851 T n = p[i]; // expected-note 4{{past-the-end}} 852 delete [] p; 853 return n; 854 } 855 static_assert(dynarray<int>(4, 0) == 1); 856 static_assert(dynarray<int>(4, 1) == 2); 857 static_assert(dynarray<int>(4, 2) == 3); 858 static_assert(dynarray<int>(4, 3) == 0); 859 static_assert(dynarray<int>(4, 4) == 0); // expected-error {{constant expression}} expected-note {{in call}} 860 static_assert(dynarray<int>(3, 2) == 3); 861 static_assert(dynarray<int>(3, 3) == 0); // expected-error {{constant expression}} expected-note {{in call}} 862 static_assert(dynarray<int>(2, 1) == 0); // expected-error {{constant expression}} expected-note {{in call}} 863 static_assert(dynarray<char>(5, 0) == 'f'); 864 static_assert(dynarray<char>(5, 1) == 'o'); 865 static_assert(dynarray<char>(5, 2) == 'x'); 866 static_assert(dynarray<char>(5, 3) == 0); // (from string) 867 static_assert(dynarray<char>(5, 4) == 0); // (from filler) 868 static_assert(dynarray<char>(5, 5) == 0); // expected-error {{constant expression}} expected-note {{in call}} 869 static_assert(dynarray<char>(4, 0) == 'f'); 870 static_assert(dynarray<char>(4, 1) == 'o'); 871 static_assert(dynarray<char>(4, 2) == 'x'); 872 static_assert(dynarray<char>(4, 3) == 0); 873 static_assert(dynarray<char>(4, 4) == 0); // expected-error {{constant expression}} expected-note {{in call}} 874 static_assert(dynarray<char>(3, 2) == 'x'); // expected-error {{constant expression}} expected-note {{in call}} 875 876 constexpr bool run_dtors_on_array_filler() { 877 struct S { 878 int times_destroyed = 0; 879 constexpr ~S() { if (++times_destroyed != 1) throw "oops"; } 880 }; 881 delete[] new S[3]; 882 return true; 883 } 884 static_assert(run_dtors_on_array_filler()); 885 886 constexpr bool erroneous_array_bound(long long n) { 887 delete[] new int[n]; // expected-note {{array bound -1 is negative}} expected-note {{array bound 4611686018427387904 is too large}} 888 return true; 889 } 890 static_assert(erroneous_array_bound(3)); 891 static_assert(erroneous_array_bound(0)); 892 static_assert(erroneous_array_bound(-1)); // expected-error {{constant expression}} expected-note {{in call}} 893 static_assert(erroneous_array_bound(1LL << 62)); // expected-error {{constant expression}} expected-note {{in call}} 894 895 constexpr bool erroneous_array_bound_nothrow(long long n) { 896 int *p = new (std::nothrow) int[n]; 897 bool result = p != 0; 898 delete[] p; 899 return result; 900 } 901 static_assert(erroneous_array_bound_nothrow(3)); 902 static_assert(erroneous_array_bound_nothrow(0)); 903 static_assert(!erroneous_array_bound_nothrow(-1)); 904 static_assert(!erroneous_array_bound_nothrow(1LL << 62)); 905 906 constexpr bool evaluate_nothrow_arg() { 907 bool ok = false; 908 delete new ((ok = true, std::nothrow)) int; 909 return ok; 910 } 911 static_assert(evaluate_nothrow_arg()); 912 913 constexpr void double_delete() { // expected-error {{never produces a constant expression}} 914 int *p = new int; 915 delete p; 916 delete p; // expected-note {{delete of pointer that has already been deleted}} 917 } 918 constexpr bool super_secret_double_delete() { 919 struct A { 920 constexpr ~A() { delete this; } // expected-note {{destruction of object that is already being destroyed}} expected-note {{in call}} 921 }; 922 delete new A; // expected-note {{in call}} 923 return true; 924 } 925 static_assert(super_secret_double_delete()); // expected-error {{constant expression}} expected-note {{in call}} 926 927 constexpr void use_after_free() { // expected-error {{never produces a constant expression}} 928 int *p = new int; 929 delete p; 930 *p = 1; // expected-note {{assignment to heap allocated object that has been deleted}} 931 } 932 constexpr void use_after_free_2() { // expected-error {{never produces a constant expression}} 933 struct X { constexpr void f() {} }; 934 X *p = new X; 935 delete p; 936 p->f(); // expected-note {{member call on heap allocated object that has been deleted}} 937 } 938 939 template<typename T> struct X { 940 std::size_t n; 941 char *p; 942 void dependent(); 943 }; 944 template<typename T> void X<T>::dependent() { 945 char *p; 946 // Ensure that we don't try to evaluate these for overflow and crash. These 947 // are all value-dependent expressions. 948 p = new char[n]; 949 p = new ((std::align_val_t)n) char[n]; 950 p = new char(n); 951 } 952 953 namespace PR47143 { 954 constexpr char *f(int n) { 955 return new char[n](); 956 } 957 const char *p = f(3); 958 constexpr bool test() { 959 char *p = f(3); 960 bool result = !p[0] && !p[1] && !p[2]; 961 delete [] p; 962 return result; 963 } 964 static_assert(test()); 965 } 966 } 967 968 struct placement_new_arg {}; 969 void *operator new(std::size_t, placement_new_arg); 970 void operator delete(void*, placement_new_arg); 971 972 namespace placement_new_delete { 973 struct ClassSpecificNew { 974 void *operator new(std::size_t); 975 }; 976 struct ClassSpecificDelete { 977 void operator delete(void*); 978 }; 979 struct DestroyingDelete { 980 void operator delete(DestroyingDelete*, std::destroying_delete_t); 981 }; 982 struct alignas(64) Overaligned {}; 983 984 constexpr bool ok() { 985 delete new Overaligned; 986 delete ::new ClassSpecificNew; 987 ::delete new ClassSpecificDelete; 988 ::delete new DestroyingDelete; 989 return true; 990 } 991 static_assert(ok()); 992 993 constexpr bool bad(int which) { 994 switch (which) { 995 case 0: 996 delete new (placement_new_arg{}) int; // expected-note {{this placement new expression is not supported in constant expressions}} 997 break; 998 999 case 1: 1000 delete new ClassSpecificNew; // expected-note {{call to class-specific 'operator new'}} 1001 break; 1002 1003 case 2: 1004 delete new ClassSpecificDelete; // expected-note {{call to class-specific 'operator delete'}} 1005 break; 1006 1007 case 3: 1008 delete new DestroyingDelete; // expected-note {{call to class-specific 'operator delete'}} 1009 break; 1010 1011 case 4: 1012 // FIXME: This technically follows the standard's rules, but it seems 1013 // unreasonable to expect implementations to support this. 1014 delete new (std::align_val_t{64}) Overaligned; // expected-note {{this placement new expression is not supported in constant expressions}} 1015 break; 1016 } 1017 1018 return true; 1019 } 1020 static_assert(bad(0)); // expected-error {{constant expression}} expected-note {{in call}} 1021 static_assert(bad(1)); // expected-error {{constant expression}} expected-note {{in call}} 1022 static_assert(bad(2)); // expected-error {{constant expression}} expected-note {{in call}} 1023 static_assert(bad(3)); // expected-error {{constant expression}} expected-note {{in call}} 1024 static_assert(bad(4)); // expected-error {{constant expression}} expected-note {{in call}} 1025 } 1026 1027 namespace delete_random_things { 1028 static_assert((delete new int, true)); 1029 static_assert((delete (int*)0, true)); 1030 int n; // expected-note {{declared here}} 1031 static_assert((delete &n, true)); // expected-error {{}} expected-note {{delete of pointer '&n' that does not point to a heap-allocated object}} 1032 struct A { int n; }; 1033 static_assert((delete &(new A)->n, true)); // expected-error {{}} expected-note {{delete of pointer to subobject '&{*new A#0}.n'}} 1034 static_assert((delete (new int + 1), true)); // expected-error {{}} expected-note {{delete of pointer '&{*new int#0} + 1' that does not point to complete object}} 1035 static_assert((delete[] (new int[3] + 1), true)); // expected-error {{}} expected-note {{delete of pointer to subobject '&{*new int[3]#0}[1]'}} 1036 static_assert((delete &(int&)(int&&)0, true)); // expected-error {{}} expected-note {{delete of pointer '&0' that does not point to a heap-allocated object}} expected-note {{temporary created here}} 1037 } 1038 1039 namespace value_dependent_delete { 1040 template<typename T> void f(T *p) { 1041 int arr[(delete p, 0)]; 1042 } 1043 } 1044 1045 namespace memory_leaks { 1046 static_assert(*new bool(true)); // expected-error {{}} expected-note {{allocation performed here was not deallocated}} 1047 1048 constexpr bool *f() { return new bool(true); } // expected-note {{allocation performed here was not deallocated}} 1049 static_assert(*f()); // expected-error {{}} 1050 1051 struct UP { 1052 bool *p; 1053 constexpr ~UP() { delete p; } 1054 constexpr bool &operator*() { return *p; } 1055 }; 1056 constexpr UP g() { return {new bool(true)}; } 1057 static_assert(*g()); // ok 1058 1059 constexpr bool h(UP p) { return *p; } 1060 static_assert(h({new bool(true)})); // ok 1061 } 1062 1063 constexpr void *operator new(std::size_t, void *p) { return p; } 1064 namespace std { 1065 template<typename T> constexpr T *construct(T *p) { return new (p) T; } 1066 template<typename T> constexpr void destroy(T *p) { p->~T(); } 1067 } 1068 1069 namespace dtor_call { 1070 struct A { int n; }; 1071 constexpr void f() { // expected-error {{never produces a constant expression}} 1072 A a; // expected-note {{destroying object 'a' whose lifetime has already ended}} 1073 a.~A(); 1074 } 1075 union U { A a; }; 1076 constexpr void g() { 1077 U u; 1078 u.a.n = 3; 1079 u.a.~A(); 1080 // There's now effectively no active union member, but we model it as if 1081 // 'a' is still the active union member (but its lifetime has ended). 1082 u.a.n = 4; // Start lifetime of 'a' again. 1083 u.a.~A(); 1084 } 1085 static_assert((g(), true)); 1086 1087 constexpr bool pseudo(bool read, bool recreate) { 1088 using T = bool; 1089 bool b = false; // expected-note {{lifetime has already ended}} 1090 // This evaluates the store to 'b'... 1091 (b = true).~T(); 1092 // ... and ends the lifetime of the object. 1093 return (read 1094 ? b // expected-note {{read of object outside its lifetime}} 1095 : true) + 1096 (recreate 1097 ? (std::construct(&b), true) 1098 : true); 1099 } 1100 static_assert(pseudo(false, false)); // expected-error {{constant expression}} expected-note {{in call}} 1101 static_assert(pseudo(true, false)); // expected-error {{constant expression}} expected-note {{in call}} 1102 static_assert(pseudo(false, true)); 1103 1104 constexpr void use_after_destroy() { 1105 A a; 1106 a.~A(); 1107 A b = a; // expected-note {{in call}} expected-note {{read of object outside its lifetime}} 1108 } 1109 static_assert((use_after_destroy(), true)); // expected-error {{}} expected-note {{in call}} 1110 1111 constexpr void double_destroy() { 1112 A a; 1113 a.~A(); 1114 a.~A(); // expected-note {{destruction of object outside its lifetime}} 1115 } 1116 static_assert((double_destroy(), true)); // expected-error {{}} expected-note {{in call}} 1117 1118 struct X { char *p; constexpr ~X() { *p++ = 'X'; } }; 1119 struct Y : X { int y; virtual constexpr ~Y() { *p++ = 'Y'; } }; 1120 struct Z : Y { int z; constexpr ~Z() override { *p++ = 'Z'; } }; 1121 union VU { 1122 constexpr VU() : z() {} 1123 constexpr ~VU() {} 1124 Z z; 1125 }; 1126 1127 constexpr bool virt_dtor(int mode, const char *expected) { 1128 char buff[4] = {}; 1129 VU vu; 1130 vu.z.p = buff; 1131 switch (mode) { 1132 case 0: 1133 vu.z.~Z(); 1134 break; 1135 case 1: 1136 ((Y&)vu.z).~Y(); 1137 break; 1138 case 2: 1139 ((X&)vu.z).~X(); 1140 break; 1141 case 3: 1142 ((Y&)vu.z).Y::~Y(); 1143 vu.z.z = 1; // ok, still have a Z (with no Y base class!) 1144 break; 1145 case 4: 1146 ((X&)vu.z).X::~X(); 1147 vu.z.y = 1; // ok, still have a Z and a Y (with no X base class!) 1148 break; 1149 } 1150 return __builtin_strcmp(expected, buff) == 0; 1151 } 1152 static_assert(virt_dtor(0, "ZYX")); 1153 static_assert(virt_dtor(1, "ZYX")); 1154 static_assert(virt_dtor(2, "X")); 1155 static_assert(virt_dtor(3, "YX")); 1156 static_assert(virt_dtor(4, "X")); 1157 1158 constexpr bool virt_delete(bool global) { 1159 struct A { 1160 virtual constexpr ~A() {} 1161 }; 1162 struct B : A { 1163 void operator delete(void *); 1164 constexpr ~B() {} 1165 }; 1166 1167 A *p = new B; 1168 if (global) 1169 ::delete p; 1170 else 1171 delete p; // expected-note {{call to class-specific 'operator delete'}} 1172 return true; 1173 } 1174 static_assert(virt_delete(true)); 1175 static_assert(virt_delete(false)); // expected-error {{}} expected-note {{in call}} 1176 1177 constexpr void use_after_virt_destroy() { 1178 char buff[4] = {}; 1179 VU vu; 1180 vu.z.p = buff; 1181 ((Y&)vu.z).~Y(); 1182 ((Z&)vu.z).z = 1; // expected-note {{assignment to object outside its lifetime}} 1183 } 1184 static_assert((use_after_virt_destroy(), true)); // expected-error {{}} expected-note {{in call}} 1185 1186 constexpr void destroy_after_lifetime() { 1187 A *p; 1188 { 1189 A a; 1190 p = &a; 1191 } 1192 p->~A(); // expected-note {{destruction of object outside its lifetime}} 1193 } 1194 static_assert((destroy_after_lifetime(), true)); // expected-error {{}} expected-note {{in call}} 1195 1196 constexpr void destroy_after_lifetime2() { 1197 A *p = []{ A a; return &a; }(); // expected-warning {{}} expected-note {{declared here}} 1198 p->~A(); // expected-note {{destruction of variable whose lifetime has ended}} 1199 } 1200 static_assert((destroy_after_lifetime2(), true)); // expected-error {{}} expected-note {{in call}} 1201 1202 constexpr void destroy_after_lifetime3() { 1203 A *p = []{ return &(A&)(A&&)A(); }(); // expected-warning {{}} expected-note {{temporary created here}} 1204 p->~A(); // expected-note {{destruction of temporary whose lifetime has ended}} 1205 } 1206 static_assert((destroy_after_lifetime3(), true)); // expected-error {{}} expected-note {{in call}} 1207 1208 constexpr void destroy_after_lifetime4() { // expected-error {{never produces a constant expression}} 1209 A *p = new A; 1210 delete p; 1211 p->~A(); // expected-note {{destruction of heap allocated object that has been deleted}} 1212 } 1213 1214 struct Extern { constexpr ~Extern() {} } extern e; 1215 constexpr void destroy_extern() { // expected-error {{never produces a constant expression}} 1216 e.~Extern(); // expected-note {{cannot modify an object that is visible outside}} 1217 } 1218 1219 constexpr A &&a_ref = A(); // expected-note {{temporary created here}} 1220 constexpr void destroy_extern_2() { // expected-error {{never produces a constant expression}} 1221 a_ref.~A(); // expected-note {{destruction of temporary is not allowed in a constant expression outside the expression that created the temporary}} 1222 } 1223 1224 struct S { 1225 constexpr S() { n = 1; } 1226 constexpr ~S() { n = 0; } 1227 int n; 1228 }; 1229 constexpr void destroy_volatile() { 1230 volatile S s; 1231 } 1232 static_assert((destroy_volatile(), true)); // ok, not volatile during construction and destruction 1233 1234 constexpr void destroy_null() { // expected-error {{never produces a constant expression}} 1235 ((A*)nullptr)->~A(); // expected-note {{destruction of dereferenced null pointer}} 1236 } 1237 1238 constexpr void destroy_past_end() { // expected-error {{never produces a constant expression}} 1239 A a; 1240 (&a+1)->~A(); // expected-note {{destruction of dereferenced one-past-the-end pointer}} 1241 } 1242 1243 constexpr void destroy_past_end_array() { // expected-error {{never produces a constant expression}} 1244 A a[2]; 1245 a[2].~A(); // expected-note {{destruction of dereferenced one-past-the-end pointer}} 1246 } 1247 1248 union As { 1249 A a, b; 1250 }; 1251 1252 constexpr void destroy_no_active() { // expected-error {{never produces a constant expression}} 1253 As as; 1254 as.b.~A(); // expected-note {{destruction of member 'b' of union with no active member}} 1255 } 1256 1257 constexpr void destroy_inactive() { // expected-error {{never produces a constant expression}} 1258 As as; 1259 as.a.n = 1; 1260 as.b.~A(); // expected-note {{destruction of member 'b' of union with active member 'a'}} 1261 } 1262 1263 constexpr void destroy_no_active_2() { // expected-error {{never produces a constant expression}} 1264 As as; 1265 as.a.n = 1; 1266 as.a.~A(); 1267 // FIXME: This diagnostic is wrong; the union has no active member now. 1268 as.b.~A(); // expected-note {{destruction of member 'b' of union with active member 'a'}} 1269 } 1270 1271 constexpr void destroy_pointer() { 1272 using T = int*; 1273 T p; 1274 // We used to think this was an -> member access because its left-hand side 1275 // is a pointer. Ensure we don't crash. 1276 p.~T(); 1277 // Put a T back so we can destroy it again. 1278 std::construct(&p); 1279 } 1280 static_assert((destroy_pointer(), true)); 1281 } 1282 1283 namespace temp_dtor { 1284 void f(); 1285 struct A { 1286 bool b; 1287 constexpr ~A() { if (b) f(); } 1288 }; 1289 1290 // We can't accept either of these unless we start actually registering the 1291 // destructors of the A temporaries to run on shutdown. It's unclear what the 1292 // intended standard behavior is so we reject this for now. 1293 constexpr A &&a = A{false}; // expected-error {{constant}} expected-note {{non-trivial destruction of lifetime-extended temporary}} 1294 void f() { a.b = true; } 1295 1296 constexpr A &&b = A{true}; // expected-error {{constant}} expected-note {{non-trivial destruction of lifetime-extended temporary}} 1297 1298 // FIXME: We could in prinicple accept this. 1299 constexpr const A &c = A{false}; // expected-error {{constant}} expected-note {{non-trivial destruction of lifetime-extended temporary}} 1300 } 1301 1302 namespace value_dependent_init { 1303 struct A { 1304 constexpr ~A() {} 1305 }; 1306 template<typename T> void f() { 1307 A a = T(); 1308 } 1309 } 1310 1311 namespace mutable_subobjects { 1312 struct A { 1313 int m; 1314 mutable int n; // expected-note 2{{here}} 1315 constexpr int f() const { return m; } 1316 constexpr int g() const { return n; } // expected-note {{mutable}} 1317 }; 1318 1319 constexpr A a = {1, 2}; 1320 static_assert(a.f() == 1); // OK (PR44958) 1321 static_assert(a.g() == 2); // expected-error {{constant}} expected-note {{in call}} 1322 1323 constexpr A b = a; // expected-error {{constant}} expected-note {{read of mutable member 'n'}} expected-note {{in call}} 1324 1325 auto &ti1 = typeid(a); 1326 auto &ti2 = typeid(a.m); 1327 auto &ti3 = typeid(a.n); 1328 1329 constexpr void destroy1() { // expected-error {{constexpr}} 1330 a.~A(); // expected-note {{cannot modify an object that is visible outside}} 1331 } 1332 using T = int; 1333 constexpr void destroy2() { // expected-error {{constexpr}} 1334 a.m.~T(); // expected-note {{cannot modify an object that is visible outside}} 1335 } 1336 constexpr void destroy3() { // expected-error {{constexpr}} 1337 a.n.~T(); // expected-note {{cannot modify an object that is visible outside}} 1338 } 1339 1340 struct X { 1341 mutable int n = 0; 1342 virtual constexpr ~X() {} 1343 }; 1344 struct Y : X { 1345 }; 1346 constexpr Y y; 1347 constexpr const X *p = &y; 1348 constexpr const Y *q = dynamic_cast<const Y*>(p); 1349 1350 // FIXME: It's unclear whether this should be accepted. The dynamic_cast is 1351 // undefined after 'z.y.~Y()`, for example. We essentially assume that all 1352 // objects that the evaluator can reach have unbounded lifetimes. (We make 1353 // the same assumption when evaluating member function calls.) 1354 struct Z { 1355 mutable Y y; 1356 }; 1357 constexpr Z z; 1358 constexpr const X *pz = &z.y; 1359 constexpr const Y *qz = dynamic_cast<const Y*>(pz); 1360 auto &zti = typeid(z.y); 1361 static_assert(&zti == &typeid(Y)); 1362 } 1363 1364 namespace PR45133 { 1365 struct A { long x; }; 1366 1367 union U; 1368 constexpr A foo(U *up); 1369 1370 union U { 1371 A a = foo(this); // expected-note {{in call to 'foo(&u)'}} 1372 int y; 1373 }; 1374 1375 constexpr A foo(U *up) { 1376 up->y = 11; // expected-note {{assignment would change active union member during the initialization of a different member}} 1377 return {42}; 1378 } 1379 1380 constinit U u = {}; // expected-error {{constant init}} expected-note {{constinit}} 1381 1382 template<int> struct X {}; 1383 1384 union V { 1385 int a, b; 1386 constexpr V(X<0>) : a(a = 1) {} // ok 1387 constexpr V(X<1>) : a(b = 1) {} // expected-note {{assignment would change active union member during the initialization of a different member}} 1388 constexpr V(X<2>) : a() { b = 1; } // ok 1389 // This case (changing the active member then changing it back) is debatable, 1390 // but it seems appropriate to reject. 1391 constexpr V(X<3>) : a((b = 1, a = 1)) {} // expected-note {{assignment would change active union member during the initialization of a different member}} 1392 }; 1393 constinit V v0 = X<0>(); 1394 constinit V v1 = X<1>(); // expected-error {{constant init}} expected-note {{constinit}} expected-note {{in call}} 1395 constinit V v2 = X<2>(); 1396 constinit V v3 = X<3>(); // expected-error {{constant init}} expected-note {{constinit}} expected-note {{in call}} 1397 } 1398 1399 namespace PR45350 { 1400 int q; 1401 struct V { int n; int *p = &n; constexpr ~V() { *p = *p * 10 + n; }}; 1402 constexpr int f(int n) { 1403 int k = 0; 1404 V *p = new V[n]; 1405 for (int i = 0; i != n; ++i) { 1406 if (p[i].p != &p[i].n) return -1; 1407 p[i].n = i; 1408 p[i].p = &k; 1409 } 1410 delete[] p; 1411 return k; 1412 } 1413 // [expr.delete]p6: 1414 // In the case of an array, the elements will be destroyed in order of 1415 // decreasing address 1416 static_assert(f(6) == 543210); 1417 } 1418 1419 namespace PR47805 { 1420 struct A { 1421 bool bad = true; 1422 constexpr ~A() { if (bad) throw; } 1423 }; 1424 constexpr bool f(A a) { a.bad = false; return true; } 1425 constexpr bool b = f(A()); 1426 1427 struct B { B *p = this; }; 1428 constexpr bool g(B b) { return &b == b.p; } 1429 static_assert(g({})); 1430 } 1431 1432 constexpr bool destroy_at_test() { 1433 int n = 0; 1434 std::destroy(&n); 1435 std::construct(&n); 1436 return true; 1437 } 1438 static_assert(destroy_at_test()); 1439 1440 namespace PR48582 { 1441 struct S { 1442 void *p = this; 1443 constexpr S() {} 1444 constexpr S(const S&) {} 1445 }; 1446 constexpr bool b = [a = S(), b = S()] { return a.p == b.p; }(); 1447 static_assert(!b); 1448 } 1449 1450 namespace PR45879 { 1451 struct A { int n; }; 1452 struct B { A a; }; 1453 constexpr A a = (A() = B().a); 1454 1455 union C { 1456 int n; 1457 A a; 1458 }; 1459 1460 constexpr bool f() { 1461 C c = {.n = 1}; 1462 c.a = B{2}.a; 1463 return c.a.n == 2; 1464 } 1465 static_assert(f()); 1466 1467 // Only syntactic assignments change the active union member. 1468 constexpr bool g() { // expected-error {{never produces a constant expression}} 1469 C c = {.n = 1}; 1470 c.a.operator=(B{2}.a); // expected-note 2{{member call on member 'a' of union with active member 'n' is not allowed in a constant expression}} 1471 return c.a.n == 2; 1472 } 1473 static_assert(g()); // expected-error {{constant expression}} expected-note {{in call}} 1474 } 1475 1476 namespace GH57431 { 1477 class B { 1478 virtual int constexpr f() = 0; 1479 }; 1480 1481 class D : B { 1482 virtual int constexpr f() = default; // expected-error {{only special member functions and comparison operators may be defaulted}} 1483 }; 1484 } 1485 1486 namespace GH57516 { 1487 class B{ 1488 virtual constexpr ~B() = 0; // expected-note {{overridden virtual function is here}} 1489 }; 1490 1491 class D : B{}; // expected-error {{deleted function '~D' cannot override a non-deleted function}} 1492 // expected-note@-1 {{destructor of 'D' is implicitly deleted because base class 'B' has an inaccessible destructor}} 1493 } 1494 1495 namespace GH67317 { 1496 constexpr unsigned char a = // expected-error {{constexpr variable 'a' must be initialized by a constant expression}} \ 1497 // expected-note {{subobject of type 'const unsigned char' is not initialized}} 1498 __builtin_bit_cast(unsigned char, *new char[3][1]); 1499 }; 1500