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();
print(T)29 template<typename T> constexpr void print(T) { not_defined(); }
30 
31 namespace ThreeWayComparison {
32   struct A {
33     int n;
operator <=>(const A & a,const A & b)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 
f()50   constexpr void f() {
51     void(1 <=> 1);
52   }
53 
54   struct MemPtr {
fooThreeWayComparison::MemPtr55     void foo() {}
barThreeWayComparison::MemPtr56     void bar() {}
57     int data;
58     int data2;
59     long data3;
60   };
61 
62   struct MemPtr2 {
fooThreeWayComparison::MemPtr263     void foo() {}
barThreeWayComparison::MemPtr264     void bar() {}
65     int data;
66     int data2;
67     long data3;
68   };
69   using MemPtrT = void (MemPtr::*)();
70 
71   using FnPtrT = void (*)();
72 
FnPtr1()73   void FnPtr1() {}
FnPtr2()74   void FnPtr2() {}
75 
76 #define CHECK(...) ((__VA_ARGS__) ? void() : throw "error")
77 #define CHECK_TYPE(...) static_assert(__is_same(__VA_ARGS__));
78 
__anon1e51dcae0102null79 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>
makeComplex(R r,I i)124 constexpr T makeComplex(R r, I i) {
125   T res{r, i};
126   return res;
127 };
128 } // namespace ThreeWayComparison
129 
for_range_init()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 
assert(bool b)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 {
fVirtual::A144     virtual constexpr char f() const { return 'A'; }
145     char a = f();
~AVirtual::A146     constexpr ~A() { assert(f() == 'A'); }
147   };
148   struct NoOverrideA : A {};
149   struct B : NonZeroOffset, NoOverrideA {
fVirtual::B150     virtual constexpr char f() const { return 'B'; }
151     char b = f();
~BVirtual::B152     constexpr ~B() { assert(f() == 'B'); }
153   };
154   struct NoOverrideB : B {};
155   struct C : NonZeroOffset, A {
fVirtual::C156     virtual constexpr char f() const { return 'C'; }
157     A *pba;
158     char c = ((A*)this)->f();
159     char ba = pba->f();
CVirtual::C160     constexpr C(A *pba) : pba(pba) {}
~CVirtual::C161     constexpr ~C() { assert(f() == 'C'); }
162   };
163   struct D : NonZeroOffset, NoOverrideB, C { // expected-warning {{inaccessible}}
fVirtual::D164     virtual constexpr char f() const { return 'D'; }
165     char d = f();
DVirtual::D166     constexpr D() : C((B*)this) {}
~DVirtual::D167     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> {
fVirtual::Covariant3199     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}}
AbstractVirtual::Abstract228     constexpr Abstract() { do_it(); } // expected-note {{in call to}}
do_itVirtual::Abstract229     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: 'DynamicCast::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: 'DynamicCast::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: 'DynamicCast::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 'DynamicCast::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 'DynamicCast::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   // expected-note@+1 {{typeid applied to object 'extern_b2' whose dynamic type is not constant}}
312   static_assert(&typeid(extern_b2) == &typeid(B2)); // expected-error {{constant expression}}
313 
314   constexpr B2 b2;
315   constexpr const B &b1 = b2;
316   static_assert(&typeid(b1) == &typeid(B2));
317 
side_effects()318   constexpr bool side_effects() {
319     // Not polymorphic nor a glvalue.
320     bool OK = true;
321     (void)typeid(OK = false, A2()); // expected-warning {{has no effect}}
322     if (!OK) return false;
323 
324     // Not polymorphic.
325     A2 a2;
326     (void)typeid(OK = false, a2); // expected-warning {{has no effect}}
327     if (!OK) return false;
328 
329     // Not a glvalue.
330     (void)typeid(OK = false, B2()); // expected-warning {{has no effect}}
331     if (!OK) return false;
332 
333     // Polymorphic glvalue: operand evaluated.
334     OK = false;
335     B2 b2;
336     (void)typeid(OK = true, b2); // expected-warning {{will be evaluated}}
337     return OK;
338   }
339   static_assert(side_effects());
340 }
341 
342 namespace Union {
343   struct Base {
344     int y; // expected-note 2{{here}}
345   };
346   struct A : Base {
347     int x;
348     int arr[3];
349     union { int p, q; };
350   };
351   union B {
352     A a;
353     int b;
354   };
read_wrong_member()355   constexpr int read_wrong_member() { // expected-error {{never produces a constant}}
356     B b = {.b = 1};
357     return b.a.x; // expected-note {{read of member 'a' of union with active member 'b'}}
358   }
change_member()359   constexpr int change_member() {
360     B b = {.b = 1};
361     b.a.x = 1;
362     return b.a.x;
363   }
364   static_assert(change_member() == 1);
change_member_then_read_wrong_member()365   constexpr int change_member_then_read_wrong_member() { // expected-error {{never produces a constant}}
366     B b = {.b = 1};
367     b.a.x = 1;
368     return b.b; // expected-note {{read of member 'b' of union with active member 'a'}}
369   }
read_wrong_member_indirect()370   constexpr int read_wrong_member_indirect() { // expected-error {{never produces a constant}}
371     B b = {.b = 1};
372     int *p = &b.a.y;
373     return *p; // expected-note {{read of member 'a' of union with active member 'b'}}
374   }
read_uninitialized()375   constexpr int read_uninitialized() {
376     B b = {.b = 1};
377     int *p = &b.a.y;
378     b.a.x = 1;
379     return *p; // expected-note {{read of uninitialized object}}
380   }
381   static_assert(read_uninitialized() == 0); // expected-error {{constant}} expected-note {{in call}}
write_wrong_member_indirect()382   constexpr void write_wrong_member_indirect() { // expected-error {{never produces a constant}}
383     B b = {.b = 1};
384     int *p = &b.a.y;
385     *p = 1; // expected-note {{assignment to member 'a' of union with active member 'b'}}
386   }
write_uninitialized()387   constexpr int write_uninitialized() {
388     B b = {.b = 1};
389     int *p = &b.a.y;
390     b.a.x = 1;
391     *p = 1;
392     return *p;
393   }
394   static_assert(write_uninitialized() == 1);
change_member_indirectly()395   constexpr int change_member_indirectly() {
396     B b = {.b = 1};
397     b.a.arr[1] = 1;
398     int &r = b.a.y;
399     r = 123;
400 
401     b.b = 2;
402     b.a.y = 3;
403     b.a.arr[2] = 4;
404     return b.a.arr[2];
405   }
406   static_assert(change_member_indirectly() == 4);
return_uninit()407   constexpr B return_uninit() {
408     B b = {.b = 1};
409     b.a.x = 2;
410     return b;
411   }
412   constexpr B uninit = return_uninit(); // expected-error {{constant expression}} expected-note {{subobject of type 'int' is not initialized}}
413   static_assert(return_uninit().a.x == 2);
return_uninit_struct()414   constexpr A return_uninit_struct() {
415     B b = {.b = 1};
416     b.a.x = 2;
417     return b.a; // expected-note {{in call to 'A(b.a)'}} expected-note {{subobject of type 'int' is not initialized}}
418   }
419   // Note that this is rejected even though return_uninit() is accepted, and
420   // return_uninit() copies the same stuff wrapped in a union.
421   //
422   // Copying a B involves copying the object representation of the union, but
423   // copying an A invokes a copy constructor that copies the object
424   // elementwise, and reading from b.a.y is undefined.
425   static_assert(return_uninit_struct().x == 2); // expected-error {{constant expression}} expected-note {{in call}}
return_init_all()426   constexpr B return_init_all() {
427     B b = {.b = 1};
428     b.a.x = 2;
429     b.a.y = 3;
430     b.a.arr[0] = 4;
431     b.a.arr[1] = 5;
432     b.a.arr[2] = 6;
433     return b;
434   }
435   static_assert(return_init_all().a.x == 2);
436   static_assert(return_init_all().a.y == 3);
437   static_assert(return_init_all().a.arr[0] == 4);
438   static_assert(return_init_all().a.arr[1] == 5);
439   static_assert(return_init_all().a.arr[2] == 6);
440   static_assert(return_init_all().a.p == 7); // expected-error {{}} expected-note {{read of member 'p' of union with no active member}}
441   static_assert(return_init_all().a.q == 8); // expected-error {{}} expected-note {{read of member 'q' of union with no active member}}
442   constexpr B init_all = return_init_all();
443 
__anon1e51dcae0302null444   constexpr bool test_no_member_change =  []{
445     union U { char dummy = {}; };
446     U u1;
447     U u2;
448     u1 = u2;
449     return true;
450   }();
451 
452   struct S1 {
453     int n;
454   };
455   struct S2 : S1 {};
456   struct S3 : S2 {};
f()457   void f() {
458     S3 s;
459     s.n = 0;
460   }
461 
462   union ref_member_1 {
463     int a;
464     int b;
465   };
466   struct ref_member_2 {
467     ref_member_1 &&r;
468   };
469   union ref_member_3 {
470     ref_member_2 a, b;
471   };
ref_member_test_1()472   constexpr int ref_member_test_1() {
473     ref_member_3 r = {.a = {.r = {.a = 1}}};
474     r.a.r.b = 2;
475     return r.a.r.b;
476   }
477   static_assert(ref_member_test_1() == 2);
ref_member_test_2()478   constexpr int ref_member_test_2() { // expected-error {{never produces a constant}}
479     ref_member_3 r = {.a = {.r = {.a = 1}}};
480     // FIXME: This note isn't great. The 'read' here is reading the referent of the reference.
481     r.b.r.b = 2; // expected-note {{read of member 'b' of union with active member 'a'}}
482     return r.b.r.b;
483   }
484 
485   namespace PR43762 {
fUnion::PR43762::A486     struct A { int x = 1; constexpr int f() { return 1; } };
gUnion::PR43762::B487     struct B : A { int y = 1; constexpr int g() { return 2; } };
488     struct C {
489       int x;
490       constexpr virtual int f() = 0;
491     };
492     struct D : C {
493       int y;
fUnion::PR43762::D494       constexpr virtual int f() override { return 3; }
495     };
496 
497     union U {
498       int n;
499       B b;
500       D d;
501     };
502 
test(int which)503     constexpr int test(int which) {
504       U u{.n = 5};
505       switch (which) {
506       case 0:
507         u.b.x = 10; // expected-note {{active member 'n'}}
508         return u.b.f();
509       case 1:
510         u.b.y = 10; // expected-note {{active member 'n'}}
511         return u.b.g();
512       case 2:
513         u.d.x = 10; // expected-note {{active member 'n'}}
514         return u.d.f();
515       case 3:
516         u.d.y = 10; // expected-note {{active member 'n'}}
517         return u.d.f();
518       }
519     }
520 
521     static_assert(test(0)); // expected-error {{}} expected-note {{in call}}
522     static_assert(test(1)); // expected-error {{}} expected-note {{in call}}
523     static_assert(test(2)); // expected-error {{}} expected-note {{in call}}
524     static_assert(test(3)); // expected-error {{}} expected-note {{in call}}
525   }
526 }
527 
528 namespace TwosComplementShifts {
529   using uint32 = __UINT32_TYPE__;
530   using int32 = __INT32_TYPE__;
531   static_assert(uint32(int32(0x1234) << 16) == 0x12340000);
532   static_assert(uint32(int32(0x1234) << 19) == 0x91a00000);
533   static_assert(uint32(int32(0x1234) << 20) == 0x23400000); // expected-warning {{requires 34 bits}}
534   static_assert(uint32(int32(0x1234) << 24) == 0x34000000); // expected-warning {{requires 38 bits}}
535   static_assert(uint32(int32(-1) << 31) == 0x80000000);
536 
537   static_assert(-1 >> 1 == -1);
538   static_assert(-1 >> 31 == -1);
539   static_assert(-2 >> 1 == -1);
540   static_assert(-3 >> 1 == -2);
541   static_assert(-4 >> 1 == -2);
542 }
543 
544 namespace Uninit {
f(bool init)545   constexpr int f(bool init) {
546     int a;
547     if (init)
548       a = 1;
549     return a; // expected-note {{read of uninitialized object}}
550   }
551   static_assert(f(true) == 1);
552   static_assert(f(false) == 1); // expected-error {{constant expression}} expected-note {{in call}}
553 
554   struct X {
555     int n; // expected-note {{declared here}}
XUninit::X556     constexpr X(bool init) {
557       if (init) n = 123;
558     }
559   };
560   constinit X x1(true);
561   constinit X x2(false); // expected-error {{constant initializer}} expected-note {{constinit}} expected-note {{subobject of type 'int' is not initialized}}
562 
563   struct Y {
564     struct Z { int n; }; // expected-note {{here}}
565     Z z1;
566     Z z2;
567     Z z3;
568     // OK: the lifetime of z1 (and its members) start before the initializer of
569     // z2 runs.
YUninit::Y570     constexpr Y() : z2{ (z1.n = 1, z1.n + 1) } { z3.n = 3; }
571     // Not OK: z3 is not in its lifetime when the initializer of z2 runs.
YUninit::Y572     constexpr Y(int) : z2{
573       (z3.n = 1, // expected-note {{assignment to object outside its lifetime}}
574        z3.n + 1) // expected-warning {{uninitialized}}
575     } { z1.n = 3; }
YUninit::Y576     constexpr Y(int, int) : z2{} {}
577   };
578   // FIXME: This is working around clang not implementing DR2026. With that
579   // fixed, we should be able to test this without the injected copy.
copy(Y y)580   constexpr Y copy(Y y) { return y; } // expected-note {{in call to 'Y(y)'}} expected-note {{subobject of type 'int' is not initialized}}
581   constexpr Y y1 = copy(Y());
582   static_assert(y1.z1.n == 1 && y1.z2.n == 2 && y1.z3.n == 3);
583 
584   constexpr Y y2 = copy(Y(0)); // expected-error {{constant expression}} expected-note {{in call}}
585 
586   static_assert(Y(0,0).z2.n == 0);
587   static_assert(Y(0,0).z1.n == 0); // expected-error {{constant expression}} expected-note {{read of uninitialized object}}
588   static_assert(Y(0,0).z3.n == 0); // expected-error {{constant expression}} expected-note {{read of uninitialized object}}
589 
590   static_assert(copy(Y(0,0)).z2.n == 0); // expected-error {{constant expression}} expected-note {{in call}}
591 
not_even_unsigned_char()592   constexpr unsigned char not_even_unsigned_char() {
593     unsigned char c;
594     return c; // expected-note {{read of uninitialized object}}
595   }
596   constexpr unsigned char x = not_even_unsigned_char(); // expected-error {{constant expression}} expected-note {{in call}}
597 
switch_var(int n)598   constexpr int switch_var(int n) {
599     switch (n) {
600     case 1:
601       int a;
602       a = n;
603       return a;
604 
605     case 2:
606       a = n;
607       return a;
608     }
609   }
610   constexpr int s1 = switch_var(1);
611   constexpr int s2 = switch_var(2);
612   static_assert(s1 == 1 && s2 == 2);
613 
switch_into_init_stmt()614   constexpr bool switch_into_init_stmt() {
615     switch (1) {
616       if (int n; false) {
617         for (int m; false;) {
618         case 1:
619           n = m = 1;
620           return n == 1 && m == 1;
621         }
622       }
623     }
624   }
625   static_assert(switch_into_init_stmt());
626 }
627 
628 namespace dtor {
lifetime_extension()629   void lifetime_extension() {
630     struct X { constexpr ~X() {} };
631     X &&a = X();
632   }
633 
ref(T && t)634   template<typename T> constexpr T &&ref(T &&t) { return (T&&)t; }
635 
636   struct Buf {
637     char buf[64];
638     int n = 0;
operator +=dtor::Buf639     constexpr void operator+=(char c) { buf[n++] = c; }
operator ==dtor::Buf640     constexpr bool operator==(const char *str) const {
641       return str[n] == 0 && __builtin_memcmp(str, buf, n) == 0;
642     }
operator !=dtor::Buf643     constexpr bool operator!=(const char *str) const { return !operator==(str); }
644   };
645 
646   struct A {
Adtor::A647     constexpr A(Buf &buf, char c) : buf(buf), c(c) { buf += c; }
~Adtor::A648     constexpr ~A() { buf += c; }
operator booldtor::A649     constexpr operator bool() const { return true; }
650     Buf &buf;
651     char c;
652   };
653 
dtor_calls_dtor()654   constexpr bool dtor_calls_dtor() {
655     union U {
656       constexpr U(Buf &buf) : u(buf, 'u') { buf += 'U'; }
657       constexpr ~U() { u.buf += 'U'; }
658       A u, v;
659     };
660 
661     struct B : A {
662       A c, &&d, e;
663       union {
664         A f;
665       };
666       U u;
667       constexpr B(Buf &buf)
668           : A(buf, 'a'), c(buf, 'c'), d(ref(A(buf, 'd'))), e(A(buf, 'e')), f(buf, 'f'), u(buf) {
669         buf += 'b';
670       }
671       constexpr ~B() {
672         buf += 'b';
673       }
674     };
675 
676     Buf buf;
677     {
678       B b(buf);
679       if (buf != "acddefuUb")
680         return false;
681     }
682     if (buf != "acddefuUbbUeca")
683       return false;
684     return true;
685   }
686   static_assert(dtor_calls_dtor());
687 
abnormal_termination(Buf & buf)688   constexpr void abnormal_termination(Buf &buf) {
689     struct Indestructible {
690       constexpr ~Indestructible(); // not defined
691     };
692 
693     A a(buf, 'a');
694     A(buf, 'b');
695     int n = 0;
696     for (A &&c = A(buf, 'c'); A d = A(buf, 'd'); A(buf, 'e')) {
697       switch (A f(buf, 'f'); A g = A(buf, 'g')) { // expected-warning {{boolean}}
698       case false: {
699         A x(buf, 'x');
700       }
701 
702       case true: {
703         A h(buf, 'h');
704         switch (n++) {
705         case 0:
706           break;
707         case 1:
708           continue;
709         case 2:
710           return;
711         }
712         break;
713       }
714 
715       default:
716         Indestructible indest;
717       }
718 
719       A j = (A(buf, 'i'), A(buf, 'j'));
720     }
721   }
722 
check_abnormal_termination()723   constexpr bool check_abnormal_termination() {
724     Buf buf = {};
725     abnormal_termination(buf);
726     return buf ==
727       "abbc"
728         "dfgh" /*break*/ "hgfijijeed"
729         "dfgh" /*continue*/ "hgfeed"
730         "dfgh" /*return*/ "hgfd"
731       "ca";
732   }
733   static_assert(check_abnormal_termination());
734 
run_dtors_on_array_filler()735   constexpr bool run_dtors_on_array_filler() {
736     struct S {
737       int times_destroyed = 0;
738       constexpr ~S() { if (++times_destroyed != 1) throw "oops"; }
739     };
740     S s[3];
741     return true;
742   }
743   static_assert(run_dtors_on_array_filler());
744 
745   // Ensure that we can handle temporary cleanups for array temporaries.
~ArrElemdtor::ArrElem746   struct ArrElem { constexpr ~ArrElem() {} };
747   using Arr = ArrElem[3];
748   static_assert((Arr{}, true));
749 }
750 
751 namespace dynamic_alloc {
752   constexpr int *p = // expected-error {{constant}} expected-note {{pointer to heap-allocated object is not a constant expression}}
753     new int; // expected-note {{heap allocation performed here}}
754 
f(int n)755   constexpr int f(int n) {
756     int *p = new int[n];
757     for (int i = 0; i != n; ++i) {
758       p[i] = i;
759     }
760     int k = 0;
761     for (int i = 0; i != n; ++i) {
762       k += p[i];
763     }
764     delete[] p;
765     return k;
766   }
767   static_assert(f(123) == 123 * 122 / 2);
768 
nvdtor()769   constexpr bool nvdtor() { // expected-error {{never produces a constant expression}}
770     struct S {
771       constexpr ~S() {}
772     };
773     struct T : S {};
774     delete (S*)new T; // expected-note {{delete of object with dynamic type 'T' through pointer to base class type 'S' with non-virtual destructor}}
775     return true;
776   }
777 
vdtor_1()778   constexpr int vdtor_1() {
779     int a;
780     struct S {
781       constexpr S(int *p) : p(p) {}
782       constexpr virtual ~S() { *p = 1; }
783       int *p;
784     };
785     struct T : S {
786       // implicit destructor defined eagerly because it is constexpr and virtual
787       using S::S;
788     };
789     delete (S*)new T(&a);
790     return a;
791   }
792   static_assert(vdtor_1() == 1);
793 
vdtor_2()794   constexpr int vdtor_2() {
795     int a = 0;
796     struct S { constexpr virtual ~S() {} };
797     struct T : S {
798       constexpr T(int *p) : p(p) {}
799       constexpr ~T() { ++*p; }
800       int *p;
801     };
802     S *p = new T{&a};
803     delete p;
804     return a;
805   }
806   static_assert(vdtor_2() == 1);
807 
vdtor_3(int mode)808   constexpr int vdtor_3(int mode) {
809     int a = 0;
810     struct S { constexpr virtual ~S() {} };
811     struct T : S {
812       constexpr T(int *p) : p(p) {}
813       constexpr ~T() { ++*p; }
814       int *p;
815     };
816     S *p = new T[3]{&a, &a, &a}; // expected-note 2{{heap allocation}}
817     switch (mode) {
818     case 0:
819       delete p; // expected-note {{non-array delete used to delete pointer to array object of type 'T [3]'}}
820       break;
821     case 1:
822       // FIXME: This diagnosic isn't great; we should mention the cast to S*
823       // somewhere in here.
824       delete[] p; // expected-note {{delete of pointer to subobject '&{*new T [3]#0}[0]'}}
825       break;
826     case 2:
827       delete (T*)p; // expected-note {{non-array delete used to delete pointer to array object of type 'T [3]'}}
828       break;
829     case 3:
830       delete[] (T*)p;
831       break;
832     }
833     return a;
834   }
835   static_assert(vdtor_3(0) == 3); // expected-error {{}} expected-note {{in call}}
836   static_assert(vdtor_3(1) == 3); // expected-error {{}} expected-note {{in call}}
837   static_assert(vdtor_3(2) == 3); // expected-error {{}} expected-note {{in call}}
838   static_assert(vdtor_3(3) == 3);
839 
delete_mismatch()840   constexpr void delete_mismatch() { // expected-error {{never produces a constant expression}}
841     delete[] // expected-note {{array delete used to delete pointer to non-array object of type 'int'}}
842       new int; // expected-note {{allocation}}
843   }
844 
845   template<typename T>
dynarray(int elems,int i)846   constexpr T dynarray(int elems, int i) {
847     T *p;
848     if constexpr (sizeof(T) == 1)
849       p = new T[elems]{"fox"}; // expected-note {{evaluated array bound 3 is too small to hold 4 explicitly initialized elements}}
850     else
851       p = new T[elems]{1, 2, 3}; // expected-note {{evaluated array bound 2 is too small to hold 3 explicitly initialized elements}}
852     T n = p[i]; // expected-note 4{{past-the-end}}
853     delete [] p;
854     return n;
855   }
856   static_assert(dynarray<int>(4, 0) == 1);
857   static_assert(dynarray<int>(4, 1) == 2);
858   static_assert(dynarray<int>(4, 2) == 3);
859   static_assert(dynarray<int>(4, 3) == 0);
860   static_assert(dynarray<int>(4, 4) == 0); // expected-error {{constant expression}} expected-note {{in call}}
861   static_assert(dynarray<int>(3, 2) == 3);
862   static_assert(dynarray<int>(3, 3) == 0); // expected-error {{constant expression}} expected-note {{in call}}
863   static_assert(dynarray<int>(2, 1) == 0); // expected-error {{constant expression}} expected-note {{in call}}
864   static_assert(dynarray<char>(5, 0) == 'f');
865   static_assert(dynarray<char>(5, 1) == 'o');
866   static_assert(dynarray<char>(5, 2) == 'x');
867   static_assert(dynarray<char>(5, 3) == 0); // (from string)
868   static_assert(dynarray<char>(5, 4) == 0); // (from filler)
869   static_assert(dynarray<char>(5, 5) == 0); // expected-error {{constant expression}} expected-note {{in call}}
870   static_assert(dynarray<char>(4, 0) == 'f');
871   static_assert(dynarray<char>(4, 1) == 'o');
872   static_assert(dynarray<char>(4, 2) == 'x');
873   static_assert(dynarray<char>(4, 3) == 0);
874   static_assert(dynarray<char>(4, 4) == 0); // expected-error {{constant expression}} expected-note {{in call}}
875   static_assert(dynarray<char>(3, 2) == 'x'); // expected-error {{constant expression}} expected-note {{in call}}
876 
run_dtors_on_array_filler()877   constexpr bool run_dtors_on_array_filler() {
878     struct S {
879       int times_destroyed = 0;
880       constexpr ~S() { if (++times_destroyed != 1) throw "oops"; }
881     };
882     delete[] new S[3];
883     return true;
884   }
885   static_assert(run_dtors_on_array_filler());
886 
erroneous_array_bound(long long n)887   constexpr bool erroneous_array_bound(long long n) {
888     delete[] new int[n]; // expected-note {{array bound -1 is negative}} expected-note {{array bound 4611686018427387904 is too large}}
889     return true;
890   }
891   static_assert(erroneous_array_bound(3));
892   static_assert(erroneous_array_bound(0));
893   static_assert(erroneous_array_bound(-1)); // expected-error {{constant expression}} expected-note {{in call}}
894   static_assert(erroneous_array_bound(1LL << 62)); // expected-error {{constant expression}} expected-note {{in call}}
895 
erroneous_array_bound_nothrow(long long n)896   constexpr bool erroneous_array_bound_nothrow(long long n) {
897     int *p = new (std::nothrow) int[n];
898     bool result = p != 0;
899     delete[] p;
900     return result;
901   }
902   static_assert(erroneous_array_bound_nothrow(3));
903   static_assert(erroneous_array_bound_nothrow(0));
904   static_assert(!erroneous_array_bound_nothrow(-1));
905   static_assert(!erroneous_array_bound_nothrow(1LL << 62));
906 
evaluate_nothrow_arg()907   constexpr bool evaluate_nothrow_arg() {
908     bool ok = false;
909     delete new ((ok = true, std::nothrow)) int;
910     return ok;
911   }
912   static_assert(evaluate_nothrow_arg());
913 
double_delete()914   constexpr void double_delete() { // expected-error {{never produces a constant expression}}
915     int *p = new int;
916     delete p;
917     delete p; // expected-note {{delete of pointer that has already been deleted}}
918   }
super_secret_double_delete()919   constexpr bool super_secret_double_delete() {
920     struct A {
921       constexpr ~A() { delete this; } // expected-note {{destruction of object that is already being destroyed}} expected-note {{in call}}
922     };
923     delete new A; // expected-note {{in call}}
924     return true;
925   }
926   static_assert(super_secret_double_delete()); // expected-error {{constant expression}} expected-note {{in call}}
927 
use_after_free()928   constexpr void use_after_free() { // expected-error {{never produces a constant expression}}
929     int *p = new int;
930     delete p;
931     *p = 1; // expected-note {{assignment to heap allocated object that has been deleted}}
932   }
use_after_free_2()933   constexpr void use_after_free_2() { // expected-error {{never produces a constant expression}}
934     struct X { constexpr void f() {} };
935     X *p = new X;
936     delete p;
937     p->f(); // expected-note {{member call on heap allocated object that has been deleted}}
938   }
939 
940   template<typename T> struct X {
941     std::size_t n;
942     char *p;
943     void dependent();
944   };
dependent()945   template<typename T> void X<T>::dependent() {
946     char *p;
947     // Ensure that we don't try to evaluate these for overflow and crash. These
948     // are all value-dependent expressions.
949     p = new char[n];
950     p = new ((std::align_val_t)n) char[n];
951     p = new char(n);
952   }
953 }
954 
955 struct placement_new_arg {};
956 void *operator new(std::size_t, placement_new_arg);
957 void operator delete(void*, placement_new_arg);
958 
959 namespace placement_new_delete {
960   struct ClassSpecificNew {
961     void *operator new(std::size_t);
962   };
963   struct ClassSpecificDelete {
964     void operator delete(void*);
965   };
966   struct DestroyingDelete {
967     void operator delete(DestroyingDelete*, std::destroying_delete_t);
968   };
969   struct alignas(64) Overaligned {};
970 
ok()971   constexpr bool ok() {
972     delete new Overaligned;
973     delete ::new ClassSpecificNew;
974     ::delete new ClassSpecificDelete;
975     ::delete new DestroyingDelete;
976     return true;
977   }
978   static_assert(ok());
979 
bad(int which)980   constexpr bool bad(int which) {
981     switch (which) {
982     case 0:
983       delete new (placement_new_arg{}) int; // expected-note {{call to placement 'operator new'}}
984       break;
985 
986     case 1:
987       delete new ClassSpecificNew; // expected-note {{call to class-specific 'operator new'}}
988       break;
989 
990     case 2:
991       delete new ClassSpecificDelete; // expected-note {{call to class-specific 'operator delete'}}
992       break;
993 
994     case 3:
995       delete new DestroyingDelete; // expected-note {{call to class-specific 'operator delete'}}
996       break;
997 
998     case 4:
999       // FIXME: This technically follows the standard's rules, but it seems
1000       // unreasonable to expect implementations to support this.
1001       delete new (std::align_val_t{64}) Overaligned; // expected-note {{placement new expression is not yet supported}}
1002       break;
1003     }
1004 
1005     return true;
1006   }
1007   static_assert(bad(0)); // expected-error {{constant expression}} expected-note {{in call}}
1008   static_assert(bad(1)); // expected-error {{constant expression}} expected-note {{in call}}
1009   static_assert(bad(2)); // expected-error {{constant expression}} expected-note {{in call}}
1010   static_assert(bad(3)); // expected-error {{constant expression}} expected-note {{in call}}
1011   static_assert(bad(4)); // expected-error {{constant expression}} expected-note {{in call}}
1012 }
1013 
1014 namespace delete_random_things {
1015   static_assert((delete new int, true));
1016   static_assert((delete (int*)0, true));
1017   int n; // expected-note {{declared here}}
1018   static_assert((delete &n, true)); // expected-error {{}} expected-note {{delete of pointer '&n' that does not point to a heap-allocated object}}
1019   struct A { int n; };
1020   static_assert((delete &(new A)->n, true)); // expected-error {{}} expected-note {{delete of pointer to subobject '&{*new delete_random_things::A#0}.n'}}
1021   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}}
1022   static_assert((delete[] (new int[3] + 1), true)); // expected-error {{}} expected-note {{delete of pointer to subobject '&{*new int [3]#0}[1]'}}
1023   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}}
1024 }
1025 
1026 namespace value_dependent_delete {
f(T * p)1027   template<typename T> void f(T *p) {
1028     int arr[(delete p, 0)];
1029   }
1030 }
1031 
1032 namespace memory_leaks {
1033   static_assert(*new bool(true)); // expected-error {{}} expected-note {{allocation performed here was not deallocated}}
1034 
f()1035   constexpr bool *f() { return new bool(true); } // expected-note {{allocation performed here was not deallocated}}
1036   static_assert(*f()); // expected-error {{}}
1037 
1038   struct UP {
1039     bool *p;
~UPmemory_leaks::UP1040     constexpr ~UP() { delete p; }
operator *memory_leaks::UP1041     constexpr bool &operator*() { return *p; }
1042   };
g()1043   constexpr UP g() { return {new bool(true)}; }
1044   static_assert(*g()); // ok
1045 
h(UP p)1046   constexpr bool h(UP p) { return *p; }
1047   static_assert(h({new bool(true)})); // ok
1048 }
1049 
1050 namespace dtor_call {
1051   struct A { int n; };
f()1052   constexpr void f() { // expected-error {{never produces a constant expression}}
1053     A a; // expected-note {{destroying object 'a' whose lifetime has already ended}}
1054     a.~A();
1055   }
1056   union U { A a; };
g()1057   constexpr void g() {
1058     U u;
1059     u.a.n = 3;
1060     u.a.~A();
1061     // There's now effectively no active union member, but we model it as if
1062     // 'a' is still the active union member (but its lifetime has ended).
1063     u.a.n = 4; // Start lifetime of 'a' again.
1064     u.a.~A();
1065   }
1066   static_assert((g(), true));
1067 
pseudo()1068   constexpr bool pseudo() {
1069     using T = bool;
1070     bool b = false;
1071     // This does evaluate the store to 'b'...
1072     (b = true).~T();
1073     // ... but does not end the lifetime of the object.
1074     return b;
1075   }
1076   static_assert(pseudo());
1077 
use_after_destroy()1078   constexpr void use_after_destroy() {
1079     A a;
1080     a.~A();
1081     A b = a; // expected-note {{in call}} expected-note {{read of object outside its lifetime}}
1082   }
1083   static_assert((use_after_destroy(), true)); // expected-error {{}} expected-note {{in call}}
1084 
double_destroy()1085   constexpr void double_destroy() {
1086     A a;
1087     a.~A();
1088     a.~A(); // expected-note {{destruction of object outside its lifetime}}
1089   }
1090   static_assert((double_destroy(), true)); // expected-error {{}} expected-note {{in call}}
1091 
~Xdtor_call::X1092   struct X { char *p; constexpr ~X() { *p++ = 'X'; } };
~Ydtor_call::Y1093   struct Y : X { int y; virtual constexpr ~Y() { *p++ = 'Y'; } };
~Zdtor_call::Z1094   struct Z : Y { int z; constexpr ~Z() override { *p++ = 'Z'; } };
1095   union VU {
VU()1096     constexpr VU() : z() {}
~VU()1097     constexpr ~VU() {}
1098     Z z;
1099   };
1100 
virt_dtor(int mode,const char * expected)1101   constexpr bool virt_dtor(int mode, const char *expected) {
1102     char buff[4] = {};
1103     VU vu;
1104     vu.z.p = buff;
1105     switch (mode) {
1106     case 0:
1107       vu.z.~Z();
1108       break;
1109     case 1:
1110       ((Y&)vu.z).~Y();
1111       break;
1112     case 2:
1113       ((X&)vu.z).~X();
1114       break;
1115     case 3:
1116       ((Y&)vu.z).Y::~Y();
1117       vu.z.z = 1; // ok, still have a Z (with no Y base class!)
1118       break;
1119     case 4:
1120       ((X&)vu.z).X::~X();
1121       vu.z.y = 1; // ok, still have a Z and a Y (with no X base class!)
1122       break;
1123     }
1124     return __builtin_strcmp(expected, buff) == 0;
1125   }
1126   static_assert(virt_dtor(0, "ZYX"));
1127   static_assert(virt_dtor(1, "ZYX"));
1128   static_assert(virt_dtor(2, "X"));
1129   static_assert(virt_dtor(3, "YX"));
1130   static_assert(virt_dtor(4, "X"));
1131 
virt_delete(bool global)1132   constexpr bool virt_delete(bool global) {
1133     struct A {
1134       virtual constexpr ~A() {}
1135     };
1136     struct B : A {
1137       void operator delete(void *);
1138       constexpr ~B() {}
1139     };
1140 
1141     A *p = new B;
1142     if (global)
1143       ::delete p;
1144     else
1145       delete p; // expected-note {{call to class-specific 'operator delete'}}
1146     return true;
1147   }
1148   static_assert(virt_delete(true));
1149   static_assert(virt_delete(false)); // expected-error {{}} expected-note {{in call}}
1150 
use_after_virt_destroy()1151   constexpr void use_after_virt_destroy() {
1152     char buff[4] = {};
1153     VU vu;
1154     vu.z.p = buff;
1155     ((Y&)vu.z).~Y();
1156     ((Z&)vu.z).z = 1; // expected-note {{assignment to object outside its lifetime}}
1157   }
1158   static_assert((use_after_virt_destroy(), true)); // expected-error {{}} expected-note {{in call}}
1159 
destroy_after_lifetime()1160   constexpr void destroy_after_lifetime() {
1161     A *p;
1162     {
1163       A a;
1164       p = &a;
1165     }
1166     p->~A(); // expected-note {{destruction of object outside its lifetime}}
1167   }
1168   static_assert((destroy_after_lifetime(), true)); // expected-error {{}} expected-note {{in call}}
1169 
destroy_after_lifetime2()1170   constexpr void destroy_after_lifetime2() {
1171     A *p = []{ A a; return &a; }(); // expected-warning {{}} expected-note {{declared here}}
1172     p->~A(); // expected-note {{destruction of variable whose lifetime has ended}}
1173   }
1174   static_assert((destroy_after_lifetime2(), true)); // expected-error {{}} expected-note {{in call}}
1175 
destroy_after_lifetime3()1176   constexpr void destroy_after_lifetime3() {
1177     A *p = []{ return &(A&)(A&&)A(); }(); // expected-warning {{}} expected-note {{temporary created here}}
1178     p->~A(); // expected-note {{destruction of temporary whose lifetime has ended}}
1179   }
1180   static_assert((destroy_after_lifetime3(), true)); // expected-error {{}} expected-note {{in call}}
1181 
destroy_after_lifetime4()1182   constexpr void destroy_after_lifetime4() { // expected-error {{never produces a constant expression}}
1183     A *p = new A;
1184     delete p;
1185     p->~A(); // expected-note {{destruction of heap allocated object that has been deleted}}
1186   }
1187 
~Externdtor_call::Extern1188   struct Extern { constexpr ~Extern() {} } extern e;
destroy_extern()1189   constexpr void destroy_extern() { // expected-error {{never produces a constant expression}}
1190     e.~Extern(); // expected-note {{cannot modify an object that is visible outside}}
1191   }
1192 
1193   constexpr A &&a_ref = A(); // expected-note {{temporary created here}}
destroy_extern_2()1194   constexpr void destroy_extern_2() { // expected-error {{never produces a constant expression}}
1195     a_ref.~A(); // expected-note {{destruction of temporary is not allowed in a constant expression outside the expression that created the temporary}}
1196   }
1197 
1198   struct S {
Sdtor_call::S1199     constexpr S() { n = 1; }
~Sdtor_call::S1200     constexpr ~S() { n = 0; }
1201     int n;
1202   };
destroy_volatile()1203   constexpr void destroy_volatile() {
1204     volatile S s;
1205   }
1206   static_assert((destroy_volatile(), true)); // ok, not volatile during construction and destruction
1207 
destroy_null()1208   constexpr void destroy_null() { // expected-error {{never produces a constant expression}}
1209     ((A*)nullptr)->~A(); // expected-note {{destruction of dereferenced null pointer}}
1210   }
1211 
destroy_past_end()1212   constexpr void destroy_past_end() { // expected-error {{never produces a constant expression}}
1213     A a;
1214     (&a+1)->~A(); // expected-note {{destruction of dereferenced one-past-the-end pointer}}
1215   }
1216 
destroy_past_end_array()1217   constexpr void destroy_past_end_array() { // expected-error {{never produces a constant expression}}
1218     A a[2];
1219     a[2].~A(); // expected-note {{destruction of dereferenced one-past-the-end pointer}}
1220   }
1221 
1222   union As {
1223     A a, b;
1224   };
1225 
destroy_no_active()1226   constexpr void destroy_no_active() { // expected-error {{never produces a constant expression}}
1227     As as;
1228     as.b.~A(); // expected-note {{destruction of member 'b' of union with no active member}}
1229   }
1230 
destroy_inactive()1231   constexpr void destroy_inactive() { // expected-error {{never produces a constant expression}}
1232     As as;
1233     as.a.n = 1;
1234     as.b.~A(); // expected-note {{destruction of member 'b' of union with active member 'a'}}
1235   }
1236 
destroy_no_active_2()1237   constexpr void destroy_no_active_2() { // expected-error {{never produces a constant expression}}
1238     As as;
1239     as.a.n = 1;
1240     as.a.~A();
1241     // FIXME: This diagnostic is wrong; the union has no active member now.
1242     as.b.~A(); // expected-note {{destruction of member 'b' of union with active member 'a'}}
1243   }
1244 
destroy_pointer()1245   constexpr void destroy_pointer() {
1246     using T = int*;
1247     T p;
1248     // We used to think this was an -> member access because its left-hand side
1249     // is a pointer. Ensure we don't crash.
1250     p.~T();
1251   }
1252   static_assert((destroy_pointer(), true));
1253 }
1254 
1255 namespace temp_dtor {
1256   void f();
1257   struct A {
1258     bool b;
~Atemp_dtor::A1259     constexpr ~A() { if (b) f(); }
1260   };
1261 
1262   // We can't accept either of these unless we start actually registering the
1263   // destructors of the A temporaries to run on shutdown. It's unclear what the
1264   // intended standard behavior is so we reject this for now.
1265   constexpr A &&a = A{false}; // expected-error {{constant}} expected-note {{non-trivial destruction of lifetime-extended temporary}}
f()1266   void f() { a.b = true; }
1267 
1268   constexpr A &&b = A{true}; // expected-error {{constant}} expected-note {{non-trivial destruction of lifetime-extended temporary}}
1269 
1270   // FIXME: We could in prinicple accept this.
1271   constexpr const A &c = A{false}; // expected-error {{constant}} expected-note {{non-trivial destruction of lifetime-extended temporary}}
1272 }
1273 
1274 namespace value_dependent_init {
1275   struct A {
~Avalue_dependent_init::A1276     constexpr ~A() {}
1277   };
f()1278   template<typename T> void f() {
1279     A a = T();
1280   }
1281 }
1282 
1283 namespace PR45350 {
1284   int q;
~VPR45350::V1285   struct V { int n; int *p = &n; constexpr ~V() { *p = *p * 10 + n; }};
f(int n)1286   constexpr int f(int n) {
1287     int k = 0;
1288     V *p = new V[n];
1289     for (int i = 0; i != n; ++i) {
1290       if (p[i].p != &p[i].n) return -1;
1291       p[i].n = i;
1292       p[i].p = &k;
1293     }
1294     delete[] p;
1295     return k;
1296   }
1297   // [expr.delete]p6:
1298   //   In the case of an array, the elements will be destroyed in order of
1299   //   decreasing address
1300   static_assert(f(6) == 543210);
1301 }
1302