1 // RUN: %clang_cc1 -fsyntax-only -verify=expected -std=c++23 %s
3 // This test covers modifications made by P2448R2.
5 // Check that there is no error when a constexpr function that never produces a
6 // constant expression, but still an error if such function is called from
8 constexpr int F(int N
) {
9 double D
= 2.0 / 0.0; // expected-note {{division by zero}}
13 constexpr int F0(int N
) {
15 double d2
= 2.0 / 0.0; // expected-note {{division by zero}}
20 constexpr int FT(T N
) {
21 double D
= 2.0 / 0.0; // expected-note {{division by zero}}
25 class NonLiteral
{ // expected-note {{'NonLiteral' is not literal because it is not an aggregate and has no constexpr constructors}}
28 ~NonLiteral() {} // expected-note {{declared here}}
31 constexpr NonLiteral
F1() {
35 constexpr int F2(NonLiteral N
) { // expected-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}}
39 class Derived
: public NonLiteral
{
40 constexpr ~Derived() {};
43 class Derived1
: public NonLiteral
{
44 constexpr Derived1() : NonLiteral () {}
49 X(); // expected-note 2{{declared here}}
53 X
& operator=(X
&& other
);
54 bool operator==(X
const&) const;
59 constexpr Wrapper() = default;
60 constexpr Wrapper(Wrapper
const&) = default;
61 constexpr Wrapper(T
const& t
) : t(t
) { }
62 constexpr Wrapper(Wrapper
&&) = default;
63 constexpr X
get() const { return t
; }
64 constexpr bool operator==(Wrapper
const&) const = default;
70 constexpr WrapperNonT() = default;
71 constexpr WrapperNonT(WrapperNonT
const&) = default;
72 constexpr WrapperNonT(X
const& t
) : t(t
) { }
73 constexpr WrapperNonT(WrapperNonT
&&) = default;
74 constexpr WrapperNonT
& operator=(WrapperNonT
&) = default;
75 constexpr WrapperNonT
& operator=(WrapperNonT
&& other
) = default;
76 constexpr X
get() const { return t
; }
77 constexpr bool operator==(WrapperNonT
const&) const = default;
82 struct NonDefaultMembers
{
83 constexpr NonDefaultMembers() {}; // expected-note 2{{non-constexpr constructor 'X' cannot be used in a constant expression}}
84 constexpr NonDefaultMembers(NonDefaultMembers
const&) {};
85 constexpr NonDefaultMembers(NonDefaultMembers
&&) {};
86 constexpr NonDefaultMembers
& operator=(NonDefaultMembers
&other
) {this->t
= other
.t
; return *this;}
87 constexpr NonDefaultMembers
& operator=(NonDefaultMembers
&& other
) {this->t
= other
.t
; return *this;}
88 constexpr bool operator==(NonDefaultMembers
const& other
) const {return this->t
== other
.t
;}
95 constexpr C1() : D(Glob
) {};
102 constexpr int A
= F(3); // expected-error {{constexpr variable 'A' must be initialized by a constant expression}}
103 // expected-note@-1 {{in call}}
105 constexpr int B
= F0(0); // expected-error {{constexpr variable 'B' must be initialized by a constant expression}}
106 // expected-note@-1 {{in call}}
108 constexpr auto C
= F1(); // expected-error {{constexpr variable cannot have non-literal type 'const NonLiteral'}}
111 constexpr auto D
= F2(L
); // expected-error {{constexpr variable 'D' must be initialized by a constant expression}}
113 constexpr auto E
= FT(1); // expected-error {{constexpr variable 'E' must be initialized by a constant expression}}
114 // expected-note@-1 {{in call}}
119 NonDefaultMembers x2
;
121 // TODO these produce notes with an invalid source location.
122 // static_assert((Wrapper<X>(), true));
123 // static_assert((WrapperNonT(), true),"");
125 static_assert((NonDefaultMembers(), true),""); // expected-error{{expression is not an integral constant expression}} \
126 // expected-note {{in call to}}
127 constexpr bool FFF
= (NonDefaultMembers() == NonDefaultMembers()); // expected-error {{must be initialized by a constant expression}} \
128 // expected-note {{in call to 'NonDefaultMembers()'}}
151 bool engaged
= false;
154 consteval
void foo() {
158 void bar() { foo(); }