[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / cxx23-invalid-constexpr.cpp
blob3229a91fbcefbbac9bdd473c3b5317a1242433a4
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
7 // constexpr context.
8 constexpr int F(int N) {
9 double D = 2.0 / 0.0; // expected-note {{division by zero}}
10 return 1;
13 constexpr int F0(int N) {
14 if (N == 0)
15 double d2 = 2.0 / 0.0; // expected-note {{division by zero}}
16 return 1;
19 template <typename T>
20 constexpr int FT(T N) {
21 double D = 2.0 / 0.0; // expected-note {{division by zero}}
22 return 1;
25 class NonLiteral { // expected-note {{'NonLiteral' is not literal because it is not an aggregate and has no constexpr constructors}}
26 public:
27 NonLiteral() {}
28 ~NonLiteral() {} // expected-note {{declared here}}
31 constexpr NonLiteral F1() {
32 return NonLiteral{};
35 constexpr int F2(NonLiteral N) { // expected-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}}
36 return 8;
39 class Derived : public NonLiteral {
40 constexpr ~Derived() {};
43 class Derived1 : public NonLiteral {
44 constexpr Derived1() : NonLiteral () {}
48 struct X {
49 X(); // expected-note 2{{declared here}}
50 X(const X&);
51 X(X&&);
52 X& operator=(X&);
53 X& operator=(X&& other);
54 bool operator==(X const&) const;
57 template <typename T>
58 struct Wrapper {
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;
65 private:
66 T t;
69 struct WrapperNonT {
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;
78 private:
79 X t;
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;}
89 X t;
92 int Glob = 0;
93 class C1 {
94 public:
95 constexpr C1() : D(Glob) {};
96 private:
97 int D;
100 void test() {
102 constexpr int A = F(3); // expected-error {{constexpr variable 'A' must be initialized by a constant expression}}
103 // expected-note@-1 {{in call}}
104 F(3);
105 constexpr int B = F0(0); // expected-error {{constexpr variable 'B' must be initialized by a constant expression}}
106 // expected-note@-1 {{in call}}
107 F0(0);
108 constexpr auto C = F1(); // expected-error {{constexpr variable cannot have non-literal type 'const NonLiteral'}}
109 F1();
110 NonLiteral L;
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}}
115 F2(L);
117 Wrapper<X> x;
118 WrapperNonT x1;
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()'}}
131 struct A {
132 A ();
133 ~A();
136 template <class T>
137 struct opt
139 union {
140 char c;
141 T data;
144 constexpr opt() {}
146 constexpr ~opt() {
147 if (engaged)
148 data.~T();
151 bool engaged = false;
154 consteval void foo() {
155 opt<A> a;
158 void bar() { foo(); }