xref: /llvm-project/clang/test/SemaCXX/constant-expression-cxx2a.cpp (revision 0a9c08c59ba61e727e9dee6d71883d9106963442)
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