160 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify=expected -std=c++23 %s2// RUN: %clang_cc1 -fsyntax-only -verify=expected -std=c++23 %s -fexperimental-new-constant-interpreter3 4// This test covers modifications made by P2448R2.5 6// Check that there is no error when a constexpr function that never produces a7// constant expression, but still an error if such function is called from8// constexpr context.9constexpr int F(int N) {10 double D = 2.0 / 0.0; // expected-note {{division by zero}}11 return 1;12}13 14constexpr int F0(int N) {15 if (N == 0)16 double d2 = 2.0 / 0.0; // expected-note {{division by zero}}17 return 1;18}19 20template <typename T>21constexpr int FT(T N) {22 double D = 2.0 / 0.0; // expected-note {{division by zero}}23 return 1;24}25 26class NonLiteral { // expected-note {{'NonLiteral' is not literal because it is not an aggregate and has no constexpr constructors}}27public:28 NonLiteral() {}29 ~NonLiteral() {} // expected-note {{declared here}}30};31 32constexpr NonLiteral F1() {33 return NonLiteral{};34}35 36constexpr int F2(NonLiteral N) { // expected-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}}37 return 8;38}39 40class Derived : public NonLiteral {41 constexpr ~Derived() {};42};43 44class Derived1 : public NonLiteral {45 constexpr Derived1() : NonLiteral () {}46};47 48 49struct X {50 X(); // expected-note 2{{declared here}}51 X(const X&);52 X(X&&);53 X& operator=(X&);54 X& operator=(X&& other);55 bool operator==(X const&) const;56};57 58template <typename T>59struct Wrapper {60 constexpr Wrapper() = default;61 constexpr Wrapper(Wrapper const&) = default;62 constexpr Wrapper(T const& t) : t(t) { }63 constexpr Wrapper(Wrapper &&) = default;64 constexpr X get() const { return t; }65 constexpr bool operator==(Wrapper const&) const = default;66 private:67 T t;68};69 70struct WrapperNonT {71 constexpr WrapperNonT() = default;72 constexpr WrapperNonT(WrapperNonT const&) = default;73 constexpr WrapperNonT(X const& t) : t(t) { }74 constexpr WrapperNonT(WrapperNonT &&) = default;75 constexpr WrapperNonT& operator=(WrapperNonT &) = default;76 constexpr WrapperNonT& operator=(WrapperNonT&& other) = default;77 constexpr X get() const { return t; }78 constexpr bool operator==(WrapperNonT const&) const = default;79 private:80 X t;81};82 83struct NonDefaultMembers {84 constexpr NonDefaultMembers() {}; // expected-note 2{{non-constexpr constructor 'X' cannot be used in a constant expression}}85 constexpr NonDefaultMembers(NonDefaultMembers const&) {};86 constexpr NonDefaultMembers(NonDefaultMembers &&) {};87 constexpr NonDefaultMembers& operator=(NonDefaultMembers &other) {this->t = other.t; return *this;}88 constexpr NonDefaultMembers& operator=(NonDefaultMembers&& other) {this->t = other.t; return *this;}89 constexpr bool operator==(NonDefaultMembers const& other) const {return this->t == other.t;}90 X t;91};92 93int Glob = 0;94class C1 {95public:96 constexpr C1() : D(Glob) {};97private:98 int D;99};100 101void test() {102 103 constexpr int A = F(3); // expected-error {{constexpr variable 'A' must be initialized by a constant expression}}104 // expected-note@-1 {{in call}}105 F(3);106 constexpr int B = F0(0); // expected-error {{constexpr variable 'B' must be initialized by a constant expression}}107 // expected-note@-1 {{in call}}108 F0(0);109 constexpr auto C = F1(); // expected-error {{constexpr variable cannot have non-literal type 'const NonLiteral'}}110 F1();111 NonLiteral L;112 constexpr auto D = F2(L); // expected-error {{constexpr variable 'D' must be initialized by a constant expression}}113 114 constexpr auto E = FT(1); // expected-error {{constexpr variable 'E' must be initialized by a constant expression}}115 // expected-note@-1 {{in call}}116 F2(L);117 118 Wrapper<X> x;119 WrapperNonT x1;120 NonDefaultMembers x2;121 122 // TODO these produce notes with an invalid source location.123 // static_assert((Wrapper<X>(), true));124 // static_assert((WrapperNonT(), true),"");125 126 static_assert((NonDefaultMembers(), true),""); // expected-error{{expression is not an integral constant expression}} \127 // expected-note {{in call to}}128 constexpr bool FFF = (NonDefaultMembers() == NonDefaultMembers()); // expected-error {{must be initialized by a constant expression}} \129 // expected-note {{in call to 'NonDefaultMembers()'}}130}131 132struct A {133 A ();134 ~A();135};136 137template <class T>138struct opt139{140 union {141 char c;142 T data;143 };144 145 constexpr opt() {}146 147 constexpr ~opt() {148 if (engaged)149 data.~T();150 }151 152 bool engaged = false;153};154 155consteval void foo() {156 opt<A> a;157}158 159void bar() { foo(); }160