// P0784R7 // { dg-do compile { target c++20 } } struct S { constexpr S () : s (0) {} constexpr ~S () {} int s; }; struct T // { dg-message "'T' is not literal because" "" { target { ! implicit_constexpr } } } { // { dg-message "'T' does not have 'constexpr' destructor" "" { target { ! implicit_constexpr } } .-1 } constexpr T () : t (0) {} ~T () {} // { dg-message "defaulted destructor calls non-'constexpr' 'T::~T\\(\\)'" "" { target { ! implicit_constexpr } } } int t; }; struct U : public S { constexpr U () : u (0) {} constexpr ~U () = default; // { dg-error "explicitly defaulted function 'constexpr U::~U\\(\\)' cannot be declared 'constexpr' because the implicit declaration is not 'constexpr'" "" { target { ! implicit_constexpr } } } int u; T t; }; struct V : virtual public S { V () : v (0) {} constexpr ~V () = default; // { dg-error "explicitly defaulted function 'constexpr V::~V\\(\\)' cannot be declared 'constexpr' because the implicit declaration is not 'constexpr'" } int v; }; struct W0 { constexpr W0 () : w (0) {} constexpr W0 (int x) : w (x) {} constexpr ~W0 () { if (w == 5) asm (""); w = 3; } int w; }; struct W1 { constexpr W1 () : w (0) {} constexpr W1 (int x) : w (x) {} constexpr ~W1 () { if (w == 5) asm (""); w = 3; } // { dg-error "inline assembly is not a constant expression" } // { dg-message "only unevaluated inline assembly is allowed in a 'constexpr' function" "" { target *-*-* } .-1 } int w; }; struct W2 { constexpr W2 () : w (0) {} constexpr W2 (int x) : w (x) {} constexpr ~W2 () { if (w == 5) asm (""); w = 3; } // { dg-error "inline assembly is not a constant expression" } // { dg-message "only unevaluated inline assembly is allowed in a 'constexpr' function" "" { target *-*-* } .-1 } int w; }; struct W3 { constexpr W3 () : w (0) {} constexpr W3 (int x) : w (x) {} constexpr ~W3 () { if (w == 5) asm (""); w = 3; } // { dg-error "inline assembly is not a constant expression" } // { dg-message "only unevaluated inline assembly is allowed in a 'constexpr' function" "" { target *-*-* } .-1 } int w; }; struct W4 { constexpr W4 () : w (0) {} constexpr W4 (int x) : w (x) {} constexpr ~W4 () { if (w == 5) asm (""); w = 3; } // { dg-error "inline assembly is not a constant expression" } // { dg-message "only unevaluated inline assembly is allowed in a 'constexpr' function" "" { target *-*-* } .-1 } int w; }; struct W5 { constexpr W5 () : w (0) {} constexpr W5 (int x) : w (x) {} constexpr ~W5 () { if (w == 5) asm (""); w = 3; } // { dg-error "inline assembly is not a constant expression" } // { dg-message "only unevaluated inline assembly is allowed in a 'constexpr' function" "" { target *-*-* } .-1 } int w; }; struct W6 { constexpr W6 () : w (0) {} constexpr W6 (int x) : w (x) {} constexpr ~W6 () { if (w == 5) asm (""); w = 3; } // { dg-error "inline assembly is not a constant expression" } // { dg-message "only unevaluated inline assembly is allowed in a 'constexpr' function" "" { target *-*-* } .-1 } int w; }; struct W7 { constexpr W7 () : w (0) {} constexpr W7 (int x) : w (x) {} constexpr ~W7 () { if (w == 5) asm (""); w = 3; } // { dg-error "inline assembly is not a constant expression" } // { dg-message "only unevaluated inline assembly is allowed in a 'constexpr' function" "" { target *-*-* } .-1 } int w; }; struct W8 { constexpr W8 () : w (0) {} constexpr W8 (int x) : w (x) {} constexpr ~W8 () { if (w == 5) asm (""); w = 3; } // { dg-error "inline assembly is not a constant expression" } // { dg-message "only unevaluated inline assembly is allowed in a 'constexpr' function" "" { target *-*-* } .-1 } int w; }; struct X : public T { constexpr X () : x (0) {} constexpr ~X () = default; // { dg-error "explicitly defaulted function 'constexpr X::~X\\(\\)' cannot be declared 'constexpr' because the implicit declaration is not 'constexpr'" "" { target { ! implicit_constexpr } } } int x; }; constexpr S s; constexpr T t; // { dg-error "the type 'const T' of 'constexpr' variable 't' is not literal" "" { target { ! implicit_constexpr } } } constexpr W0 w1; constexpr W0 w2 = 12; constexpr W1 w3 = 5; // { dg-message "in 'constexpr' expansion of" } constexpr W0 w4[3] = { 1, 2, 3 }; constexpr W2 w5[3] = { 4, 5, 6 }; // { dg-message "in 'constexpr' expansion of" } void f1 () { constexpr S s2; constexpr W0 w6; constexpr W0 w7 = 12; constexpr W3 w8 = 5; // { dg-message "in 'constexpr' expansion of" } constexpr W0 w9[3] = { 1, 2, 3 }; constexpr W4 w10[3] = { 4, 5, 6 }; // { dg-message "in 'constexpr' expansion of" } } constexpr int f2 () { constexpr S s3; constexpr W0 w11; constexpr W0 w12 = 12; constexpr W5 w13 = 5; // { dg-message "in 'constexpr' expansion of" } constexpr W0 w14[3] = { 1, 2, 3 }; constexpr W6 w15[3] = { 4, 5, 6 }; // { dg-message "in 'constexpr' expansion of" } return 0; } constexpr int f3 () { S s3; W0 w11; W0 w12 = 12; W0 w14[3] = { 1, 2, 3 }; return 0; } constexpr int x3 = f3 (); constexpr int f4 () { W7 w13 = 5; return 0; } // { dg-message "in 'constexpr' expansion of" } constexpr int x4 = f4 (); // { dg-message "in 'constexpr' expansion of" } constexpr int f5 () { W8 w15[3] = { 4, 5, 6 }; // { dg-message "in 'constexpr' expansion of" } return 0; } constexpr int x5 = f5 (); // { dg-message "in 'constexpr' expansion of" } void f6 () { constexpr T t2; // { dg-error "the type 'const T' of 'constexpr' variable 't2' is not literal" "" { target { ! implicit_constexpr } } } } constexpr int f7 () { constexpr T t3; // { dg-error "the type 'const T' of 'constexpr' variable 't3' is not literal" "" { target { ! implicit_constexpr } } } return 0; } constexpr int f8 () { T t4; // { dg-error "variable 't4' of non-literal type 'T' in 'constexpr' function only available with" "" { target { c++20_down && { ! implicit_constexpr } } } } return 0; }