12b4fa534SRichard Smith // RUN: %clang_cc1 -std=c++2a -verify %s 22b4fa534SRichard Smith 32b4fa534SRichard Smith constexpr int non_class = 42; 42b4fa534SRichard Smith constexpr int arr_non_class[5] = {1, 2, 3}; 52b4fa534SRichard Smith 62b4fa534SRichard Smith struct A { 72b4fa534SRichard Smith int member = 1; ~AA82b4fa534SRichard Smith constexpr ~A() { member = member + 1; } 92b4fa534SRichard Smith }; 102b4fa534SRichard Smith constexpr A class_ = {}; 112b4fa534SRichard Smith constexpr A arr_class[5] = {{}, {}}; 122b4fa534SRichard Smith 132b4fa534SRichard Smith struct Mutable { 142b4fa534SRichard Smith mutable int member = 1; // expected-note {{declared here}} ~MutableMutable152b4fa534SRichard Smith constexpr ~Mutable() { member = member + 1; } // expected-note {{read of mutable member}} 162b4fa534SRichard Smith }; 172b4fa534SRichard Smith constexpr Mutable mut_member; // expected-error {{must have constant destruction}} expected-note {{in call}} 182b4fa534SRichard Smith 192b4fa534SRichard Smith struct MutableStore { 202b4fa534SRichard Smith mutable int member = 1; // expected-note {{declared here}} ~MutableStoreMutableStore212b4fa534SRichard Smith constexpr ~MutableStore() { member = 2; } // expected-note {{assignment to mutable member}} 222b4fa534SRichard Smith }; 232b4fa534SRichard Smith constexpr MutableStore mut_store; // expected-error {{must have constant destruction}} expected-note {{in call}} 242b4fa534SRichard Smith 252b4fa534SRichard Smith // Note: the constant destruction rules disallow this example even though hcm.n is a const object. 262b4fa534SRichard Smith struct MutableConst { 272b4fa534SRichard Smith struct HasConstMember { 282b4fa534SRichard Smith const int n = 4; 292b4fa534SRichard Smith }; 302b4fa534SRichard Smith mutable HasConstMember hcm; // expected-note {{here}} ~MutableConstMutableConst312b4fa534SRichard Smith constexpr ~MutableConst() { 322b4fa534SRichard Smith int q = hcm.n; // expected-note {{read of mutable}} 332b4fa534SRichard Smith } 342b4fa534SRichard Smith }; 352b4fa534SRichard Smith constexpr MutableConst mc; // expected-error {{must have constant destruction}} expected-note {{in call}} 362b4fa534SRichard Smith 372b4fa534SRichard Smith struct Temporary { 382b4fa534SRichard Smith int &&temp; ~TemporaryTemporary392b4fa534SRichard Smith constexpr ~Temporary() { 402b4fa534SRichard Smith int n = temp; // expected-note {{outside the expression that created the temporary}} 412b4fa534SRichard Smith } 422b4fa534SRichard Smith }; 432b4fa534SRichard Smith constexpr Temporary t = {3}; // expected-error {{must have constant destruction}} expected-note {{created here}} expected-note {{in call}} 44e328d68dSAaron Ballman 45e328d68dSAaron Ballman namespace P1073R3 { f()46*880fa7faSSam McCallconsteval int f() { return 42; } // expected-note 2 {{declared here}} g()47e328d68dSAaron Ballmanconsteval auto g() { return f; } h(int (* p)()=g ())48a2739f11SMariya Podchishchaevaconsteval int h(int (*p)() = g()) { return p(); } 49a2739f11SMariya Podchishchaeva constexpr int r = h(); 50*880fa7faSSam McCall constexpr auto e = g(); // expected-error {{call to consteval function 'P1073R3::g' is not a constant expression}} \ 51*880fa7faSSam McCall expected-error {{constexpr variable 'e' must be initialized by a constant expression}} \ 52*880fa7faSSam McCall expected-note 2 {{pointer to a consteval declaration is not a constant expression}} 53a2739f11SMariya Podchishchaeva static_assert(r == 42); 54e328d68dSAaron Ballman } // namespace P1073R3 55