| // RUN: %clang_cc1 -std=c++2a -emit-llvm-only -Wno-unused-value -Wno-vla %s -verify | 
 |  | 
 | typedef __SIZE_TYPE__ size_t; | 
 |  | 
 | namespace basic_sema { | 
 |  | 
 | consteval int f1(int i) { | 
 |   return i; | 
 | } | 
 |  | 
 | consteval constexpr int f2(int i) { | 
 |   //expected-error@-1 {{cannot combine}} | 
 |   return i; | 
 | } | 
 |  | 
 | constexpr auto l_eval = [](int i) consteval { | 
 | // expected-note@-1+ {{declared here}} | 
 |  | 
 |   return i; | 
 | }; | 
 |  | 
 | constexpr consteval int f3(int i) { | 
 |   //expected-error@-1 {{cannot combine}} | 
 |   return i; | 
 | } | 
 |  | 
 | struct A { | 
 |   consteval int f1(int i) const { | 
 | // expected-note@-1 {{declared here}} | 
 |     return i; | 
 |   } | 
 |   consteval A(int i); | 
 |   consteval A() = default; | 
 |   consteval ~A() = default; // expected-error {{destructor cannot be declared consteval}} | 
 | }; | 
 |  | 
 | consteval struct B {}; // expected-error {{struct cannot be marked consteval}} | 
 |  | 
 | consteval typedef B b; // expected-error {{typedef cannot be consteval}} | 
 |  | 
 | consteval int redecl() {return 0;} // expected-note {{previous declaration is here}} | 
 | constexpr int redecl() {return 0;} // expected-error {{constexpr declaration of 'redecl' follows consteval declaration}} | 
 |  | 
 | consteval int i = 0; // expected-error {{consteval can only be used in function declarations}} | 
 |  | 
 | consteval int; // expected-error {{consteval can only be used in function declarations}} | 
 |  | 
 | consteval int f1() {} // expected-error {{no return statement in consteval function}} | 
 |  | 
 | struct C { | 
 |   C() {} | 
 |   ~C() {} | 
 | }; | 
 |  | 
 | struct D { | 
 |   C c; | 
 |   consteval D() = default; // expected-error {{cannot be marked consteval}} | 
 |   consteval ~D() = default; // expected-error {{destructor cannot be declared consteval}} | 
 | }; | 
 |  | 
 | struct E : C { | 
 |   consteval ~E() {} // expected-error {{cannot be declared consteval}} | 
 | }; | 
 | } | 
 |  | 
 | consteval int main() { // expected-error {{'main' is not allowed to be declared consteval}} | 
 |   return 0; | 
 | } | 
 |  | 
 | consteval int f_eval(int i) { | 
 | // expected-note@-1+ {{declared here}} | 
 |   return i; | 
 | } | 
 |  | 
 | namespace taking_address { | 
 |  | 
 | using func_type = int(int); | 
 |  | 
 | func_type* p1 = (&f_eval); | 
 | // expected-error@-1 {{take address}} | 
 | func_type* p7 = __builtin_addressof(f_eval); | 
 | // expected-error@-1 {{take address}} | 
 |  | 
 | auto p = f_eval; | 
 | // expected-error@-1 {{take address}} | 
 |  | 
 | auto m1 = &basic_sema::A::f1; | 
 | // expected-error@-1 {{take address}} | 
 | auto l1 = &decltype(basic_sema::l_eval)::operator(); | 
 | // expected-error@-1 {{take address}} | 
 |  | 
 | consteval int f(int i) { | 
 | // expected-note@-1+ {{declared here}} | 
 |   return i; | 
 | } | 
 |  | 
 | auto ptr = &f; | 
 | // expected-error@-1 {{take address}} | 
 |  | 
 | auto f1() { | 
 |   return &f; | 
 | // expected-error@-1 {{take address}} | 
 | } | 
 |  | 
 | } | 
 |  | 
 | namespace invalid_function { | 
 |  | 
 | struct A { | 
 |   consteval void *operator new(size_t count); | 
 |   // expected-error@-1 {{'operator new' cannot be declared consteval}} | 
 |   consteval void *operator new[](size_t count); | 
 |   // expected-error@-1 {{'operator new[]' cannot be declared consteval}} | 
 |   consteval void operator delete(void* ptr); | 
 |   // expected-error@-1 {{'operator delete' cannot be declared consteval}} | 
 |   consteval void operator delete[](void* ptr); | 
 |   // expected-error@-1 {{'operator delete[]' cannot be declared consteval}} | 
 |   consteval ~A() {} | 
 |   // expected-error@-1 {{destructor cannot be declared consteval}} | 
 | }; | 
 |  | 
 | } | 
 |  | 
 | namespace nested { | 
 | consteval int f() { | 
 |   return 0; | 
 | } | 
 |  | 
 | consteval int f1(...) { | 
 |   return 1; | 
 | } | 
 |  | 
 | enum E {}; | 
 |  | 
 | using T = int(&)(); | 
 |  | 
 | consteval auto operator+ (E, int(*a)()) { | 
 |   return 0; | 
 | } | 
 |  | 
 | void d() { | 
 |   auto i = f1(E() + &f); | 
 | } | 
 |  | 
 | auto l0 = [](auto) consteval { | 
 |   return 0; | 
 | }; | 
 |  | 
 | int i0 = l0(&f1); | 
 |  | 
 | int i1 = f1(l0(4)); | 
 |  | 
 | int i2 = f1(&f1, &f1, &f1, &f1, &f1, &f1, &f1); | 
 |  | 
 | int i3 = f1(f1(f1(&f1, &f1), f1(&f1, &f1), f1(f1(&f1, &f1), &f1))); | 
 |  | 
 | } | 
 |  | 
 | namespace user_defined_literal { | 
 |  | 
 | consteval int operator""_test(unsigned long long i) { | 
 | // expected-note@-1+ {{declared here}} | 
 |   return 0; | 
 | } | 
 |  | 
 | int i = 0_test; | 
 |  | 
 | auto ptr = &operator""_test; | 
 | // expected-error@-1 {{take address}} | 
 |  | 
 | consteval auto operator""_test1(unsigned long long i) { | 
 |   return &f_eval; | 
 | } | 
 |  | 
 | auto i1 = 0_test1; // expected-error {{is not a constant expression}} | 
 | // expected-note@-1 {{is not a constant expression}} | 
 |  | 
 | } | 
 |  | 
 | namespace return_address { | 
 |  | 
 | consteval int f() { | 
 | // expected-note@-1 {{declared here}} | 
 |   return 0; | 
 | } | 
 |  | 
 | consteval int(*ret1(int i))() { | 
 |   return &f; | 
 | } | 
 |  | 
 | auto ptr = ret1(0); | 
 | // expected-error@-1 {{is not a constant expression}} | 
 | // expected-note@-2 {{pointer to a consteval}} | 
 |  | 
 | struct A { | 
 |   consteval int f(int) { | 
 |     // expected-note@-1+ {{declared here}} | 
 |     return 0; | 
 |   } | 
 | }; | 
 |  | 
 | using mem_ptr_type = int (A::*)(int); | 
 |  | 
 | template<mem_ptr_type ptr> | 
 | struct C {}; | 
 |  | 
 | C<&A::f> c; | 
 | // expected-error@-1 {{is not a constant expression}} | 
 | // expected-note@-2 {{pointer to a consteval}} | 
 |  | 
 | consteval mem_ptr_type ret2() { | 
 |   return &A::f; | 
 | } | 
 |  | 
 | C<ret2()> c1; | 
 | // expected-error@-1 {{is not a constant expression}} | 
 | // expected-note@-2 {{pointer to a consteval}} | 
 |  | 
 | } | 
 |  | 
 | namespace context { | 
 |  | 
 | int g_i; | 
 | // expected-note@-1 {{declared here}} | 
 |  | 
 | consteval int f(int) { | 
 |   return 0; | 
 | } | 
 |  | 
 | constexpr int c_i = 0; | 
 |  | 
 | int t1 = f(g_i); | 
 | // expected-error@-1 {{is not a constant expression}} | 
 | // expected-note@-2 {{read of non-const variable}} | 
 | int t3 = f(c_i); | 
 |  | 
 | constexpr int f_c(int i) { | 
 | // expected-note@-1 {{declared here}} | 
 |   int t = f(i); | 
 | // expected-error@-1 {{is not a constant expression}} | 
 | // expected-note@-2 {{function parameter}} | 
 |   return f(0); | 
 | } | 
 |  | 
 | consteval int f_eval(int i) { | 
 |   return f(i); | 
 | } | 
 |  | 
 | auto l0 = [](int i) consteval { | 
 |   return f(i); | 
 | }; | 
 |  | 
 | auto l1 = [](int i) constexpr { // expected-error{{cannot take address of immediate call operator}} \ | 
 |                                 // expected-note {{declared here}} | 
 |   int t = f(i); | 
 |   return f(0); | 
 | }; | 
 |  | 
 | int(*test)(int)  = l1; | 
 |  | 
 | } | 
 |  | 
 | namespace consteval_lambda_in_template { | 
 | struct S { | 
 |     int *value; | 
 |     constexpr S(int v) : value(new int {v}) {} | 
 |     constexpr ~S() { delete value; } | 
 | }; | 
 | consteval S fn() { return S(5); } | 
 |  | 
 | template <typename T> | 
 | void fn2() { | 
 |     (void)[]() consteval -> int { | 
 |       return *(fn().value);  // OK, immediate context | 
 |     }; | 
 | } | 
 |  | 
 | void caller() { | 
 |     fn2<int>(); | 
 | } | 
 | } | 
 |  | 
 | namespace std { | 
 |  | 
 | template <typename T> struct remove_reference { using type = T; }; | 
 | template <typename T> struct remove_reference<T &> { using type = T; }; | 
 | template <typename T> struct remove_reference<T &&> { using type = T; }; | 
 |  | 
 | template <typename T> | 
 | constexpr typename std::remove_reference<T>::type&& move(T &&t) noexcept { | 
 |   return static_cast<typename std::remove_reference<T>::type &&>(t); | 
 | } | 
 |  | 
 | } | 
 |  | 
 | namespace temporaries { | 
 |  | 
 | struct A { | 
 |   consteval int ret_i() const { return 0; } | 
 |   consteval A ret_a() const { return A{}; } | 
 |   constexpr ~A() { } | 
 | }; | 
 |  | 
 | consteval int by_value_a(A a) { return a.ret_i(); } | 
 |  | 
 | consteval int const_a_ref(const A &a) { | 
 |   return a.ret_i(); | 
 | } | 
 |  | 
 | consteval int rvalue_ref(const A &&a) { | 
 |   return a.ret_i(); | 
 | } | 
 |  | 
 | consteval const A &to_lvalue_ref(const A &&a) { | 
 |   return a; | 
 | } | 
 |  | 
 | void test() { | 
 |   constexpr A a {}; | 
 |   { int k = A().ret_i(); } | 
 |   { A k = A().ret_a(); } | 
 |   { A k = to_lvalue_ref(A()); }// expected-error {{is not a constant expression}} | 
 |   // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}} | 
 |   { A k = to_lvalue_ref(A().ret_a()); } // expected-error {{is not a constant expression}} | 
 |   // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}} | 
 |   { int k = A().ret_a().ret_i(); } | 
 |   { int k = by_value_a(A()); } | 
 |   { int k = const_a_ref(A()); } | 
 |   { int k = const_a_ref(a); } | 
 |   { int k = rvalue_ref(A()); } | 
 |   { int k = rvalue_ref(std::move(a)); } | 
 |   { int k = const_a_ref(A().ret_a()); } | 
 |   { int k = const_a_ref(to_lvalue_ref(A().ret_a())); } | 
 |   { int k = const_a_ref(to_lvalue_ref(std::move(a))); } | 
 |   { int k = by_value_a(A().ret_a()); } | 
 |   { int k = by_value_a(to_lvalue_ref(std::move(a))); } | 
 |   { int k = (A().ret_a(), A().ret_i()); } | 
 |   { int k = (const_a_ref(A().ret_a()), A().ret_i()); }// | 
 | } | 
 |  | 
 | } | 
 |  | 
 | namespace alloc { | 
 |  | 
 | consteval int f() { | 
 |   int *A = new int(0); | 
 | // expected-note@-1+ {{allocation performed here was not deallocated}} | 
 |   return *A; | 
 | } | 
 |  | 
 | int i1 = f(); // expected-error {{is not a constant expression}} | 
 |  | 
 | struct A { | 
 |   int* p = new int(42); | 
 |   // expected-note@-1+ {{heap allocation performed here}} | 
 |   consteval int ret_i() const { return p ? *p : 0; } | 
 |   consteval A ret_a() const { return A{}; } | 
 |   constexpr ~A() { delete p; } | 
 | }; | 
 |  | 
 | consteval int by_value_a(A a) { return a.ret_i(); } | 
 |  | 
 | consteval int const_a_ref(const A &a) { | 
 |   return a.ret_i(); | 
 | } | 
 |  | 
 | consteval int rvalue_ref(const A &&a) { | 
 |   return a.ret_i(); | 
 | } | 
 |  | 
 | consteval const A &to_lvalue_ref(const A &&a) { | 
 |   return a; | 
 | } | 
 |  | 
 | void test() { | 
 |   constexpr A a{ nullptr }; | 
 |   { int k = A().ret_i(); } | 
 |   { A k = A().ret_a(); } // expected-error {{is not a constant expression}} | 
 |   // expected-note@-1 {{is not a constant expression}} | 
 |   { A k = to_lvalue_ref(A()); } // expected-error {{is not a constant expression}} | 
 |   // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}} | 
 |   { A k = to_lvalue_ref(A().ret_a()); } | 
 |   // expected-note@-1 {{reference to temporary is not a constant expression}} | 
 |   // expected-error@-2 {{'alloc::to_lvalue_ref' is not a constant expression}} | 
 |   // expected-note@-3 {{temporary created here}} | 
 |   { int k = A().ret_a().ret_i(); } | 
 |   // expected-error@-1 {{'alloc::A::ret_a' is not a constant expression}} | 
 |   // expected-note@-2 {{heap-allocated object is not a constant expression}} | 
 |   { int k = by_value_a(A()); } | 
 |   { int k = const_a_ref(A()); } | 
 |   { int k = const_a_ref(a); } | 
 |   { int k = rvalue_ref(A()); } | 
 |   { int k = rvalue_ref(std::move(a)); } | 
 |   { int k = const_a_ref(A().ret_a()); } | 
 |   { int k = const_a_ref(to_lvalue_ref(A().ret_a())); } | 
 |   { int k = const_a_ref(to_lvalue_ref(std::move(a))); } | 
 |   { int k = by_value_a(A().ret_a()); } | 
 |   { int k = by_value_a(to_lvalue_ref(static_cast<const A&&>(a))); } | 
 |   { int k = (A().ret_a(), A().ret_i()); }// expected-error {{is not a constant expression}} | 
 |   // expected-note@-1 {{is not a constant expression}} | 
 |   { int k = (const_a_ref(A().ret_a()), A().ret_i()); } | 
 | } | 
 |  | 
 | } | 
 |  | 
 | namespace self_referencing { | 
 |  | 
 | struct S { | 
 |   S* ptr = nullptr; | 
 |   constexpr S(int i) : ptr(this) { | 
 |     if (this == ptr && i) | 
 |       ptr = nullptr; | 
 |   } | 
 |   constexpr ~S() {} | 
 | }; | 
 |  | 
 | consteval S f(int i) { | 
 |   return S(i); | 
 | } | 
 |  | 
 | void test() { | 
 |   S s(1); | 
 |   s = f(1); | 
 |   s = f(0); // expected-error {{is not a constant expression}} | 
 |   // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}} | 
 | } | 
 |  | 
 | struct S1 { | 
 |   S1* ptr = nullptr; | 
 |   consteval S1(int i) : ptr(this) { | 
 |     if (this == ptr && i) | 
 |       ptr = nullptr; | 
 |   } | 
 |   constexpr ~S1() {} | 
 | }; | 
 |  | 
 | void test1() { | 
 |   S1 s(1); | 
 |   s = S1(1); | 
 |   s = S1(0); // expected-error {{is not a constant expression}} | 
 |   // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}} | 
 | } | 
 |  | 
 | } | 
 | namespace ctor { | 
 |  | 
 | consteval int f_eval() { // expected-note+ {{declared here}} | 
 |   return 0; | 
 | } | 
 |  | 
 | namespace std { | 
 |   struct strong_ordering { | 
 |     int n; | 
 |     static const strong_ordering less, equal, greater; | 
 |   }; | 
 |   constexpr strong_ordering strong_ordering::less = {-1}; | 
 |   constexpr strong_ordering strong_ordering::equal = {0}; | 
 |   constexpr strong_ordering strong_ordering::greater = {1}; | 
 |   constexpr bool operator!=(strong_ordering, int); | 
 | } | 
 |  | 
 | namespace override { | 
 |   struct A { | 
 |     virtual consteval void f(); // expected-note {{overridden}} | 
 |     virtual void g(); // expected-note {{overridden}} | 
 |   }; | 
 |   struct B : A { | 
 |     consteval void f(); | 
 |     void g(); | 
 |   }; | 
 |   struct C : A { | 
 |     void f(); // expected-error {{non-consteval function 'f' cannot override a consteval function}} | 
 |     consteval void g(); // expected-error {{consteval function 'g' cannot override a non-consteval function}} | 
 |   }; | 
 |  | 
 |   namespace implicit_equals_1 { | 
 |     struct Y; | 
 |     struct X { | 
 |       std::strong_ordering operator<=>(const X&) const; | 
 |       constexpr bool operator==(const X&) const; | 
 |       virtual consteval bool operator==(const Y&) const; // expected-note {{here}} | 
 |     }; | 
 |     struct Y : X { | 
 |       std::strong_ordering operator<=>(const Y&) const = default; | 
 |       // expected-error@-1 {{non-consteval function 'operator==' cannot override a consteval function}} | 
 |     }; | 
 |   } | 
 |  | 
 |   namespace implicit_equals_2 { | 
 |     struct Y; | 
 |     struct X { | 
 |       constexpr std::strong_ordering operator<=>(const X&) const; | 
 |       constexpr bool operator==(const X&) const; | 
 |       virtual bool operator==(const Y&) const; // expected-note {{here}} | 
 |     }; | 
 |     struct Y : X { | 
 |       consteval std::strong_ordering operator<=>(const Y&) const = default; | 
 |       // expected-error@-1 {{consteval function 'operator==' cannot override a non-consteval function}} | 
 |     }; | 
 |   } | 
 | } | 
 |  | 
 | namespace operator_rewrite { | 
 |   struct A { | 
 |     friend consteval int operator<=>(const A&, const A&) { return 0; } | 
 |   }; | 
 |   const bool k = A() < A(); | 
 |   static_assert(!k); | 
 |  | 
 |   A a; | 
 |   bool k2 = A() < a; // OK, does not access 'a'. | 
 |  | 
 |   struct B { | 
 |     friend consteval int operator<=>(const B &l, const B &r) { return r.n - l.n; } // expected-note {{read of }} | 
 |     int n; | 
 |   }; | 
 |   static_assert(B() >= B()); | 
 |   B b; // expected-note {{here}} | 
 |   bool k3 = B() < b; // expected-error-re {{call to consteval function '{{.*}}::operator<=>' is not a constant expression}} expected-note {{in call}} | 
 | } | 
 |  | 
 | struct A { | 
 |   int(*ptr)(); | 
 |   consteval A(int(*p)() = nullptr) : ptr(p) {} | 
 | }; | 
 |  | 
 | struct B { | 
 |   int(*ptr)(); | 
 |   B() : ptr(nullptr) {} | 
 |   consteval B(int(*p)(), int) : ptr(p) {} | 
 | }; | 
 |  | 
 | void test() { | 
 |   { A a; } | 
 |   { A a(&f_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { B b(nullptr, 0); } | 
 |   { B b(&f_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { A a{}; } | 
 |   { A a{&f_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { B b{nullptr, 0}; } | 
 |   { B b{&f_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { A a = A(); } | 
 |   { A a = A(&f_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { B b = B(nullptr, 0); } | 
 |   { B b = B(&f_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { A a = A{}; } | 
 |   { A a = A{&f_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { B b = B{nullptr, 0}; } | 
 |   { B b = B{&f_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { A a; a = A(); } | 
 |   { A a; a = A(&f_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { B b; b = B(nullptr, 0); } | 
 |   { B b; b = B(&f_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { A a; a = A{}; } | 
 |   { A a; a = A{&f_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { B b; b = B{nullptr, 0}; } | 
 |   { B b; b = B{&f_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { A* a; a = new A(); } | 
 |   { A* a; a = new A(&f_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { B* b; b = new B(nullptr, 0); } | 
 |   { B* b; b = new B(&f_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { A* a; a = new A{}; } | 
 |   { A* a; a = new A{&f_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { B* b; b = new B{nullptr, 0}; } | 
 |   { B* b; b = new B{&f_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 | } | 
 |  | 
 | } | 
 |  | 
 | namespace copy_ctor { | 
 |  | 
 | consteval int f_eval() { // expected-note+ {{declared here}} | 
 |   return 0; | 
 | } | 
 |  | 
 | struct Copy { | 
 |   int(*ptr)(); | 
 |   constexpr Copy(int(*p)() = nullptr) : ptr(p) {} | 
 |   consteval Copy(const Copy&) = default; | 
 | }; | 
 |  | 
 | constexpr const Copy &to_lvalue_ref(const Copy &&a) { | 
 |   return a; | 
 | } | 
 |  | 
 | void test() { | 
 |   constexpr const Copy C; | 
 |   // there is no the copy constructor call when its argument is a prvalue because of garanteed copy elision. | 
 |   // so we need to test with both prvalue and xvalues. | 
 |   { Copy c(C); } | 
 |   { Copy c((Copy(&f_eval))); }// expected-error {{cannot take address of consteval}} | 
 |   { Copy c(std::move(C)); } | 
 |   { Copy c(std::move(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy c(to_lvalue_ref((Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy c(to_lvalue_ref(std::move(C))); } | 
 |   { Copy c(to_lvalue_ref(std::move(Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy c = Copy(C); } | 
 |   { Copy c = Copy(Copy(&f_eval)); }// expected-error {{cannot take address of consteval}} | 
 |   { Copy c = Copy(std::move(C)); } | 
 |   { Copy c = Copy(std::move(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy c = Copy(to_lvalue_ref(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy c = Copy(to_lvalue_ref(std::move(C))); } | 
 |   { Copy c = Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy c; c = Copy(C); } | 
 |   { Copy c; c = Copy(Copy(&f_eval)); }// expected-error {{cannot take address of consteval}} | 
 |   { Copy c; c = Copy(std::move(C)); } | 
 |   { Copy c; c = Copy(std::move(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy c; c = Copy(to_lvalue_ref(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy c; c = Copy(to_lvalue_ref(std::move(C))); } | 
 |   { Copy c; c = Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy* c; c = new Copy(C); } | 
 |   { Copy* c; c = new Copy(Copy(&f_eval)); }// expected-error {{cannot take address of consteval}} | 
 |   { Copy* c; c = new Copy(std::move(C)); } | 
 |   { Copy* c; c = new Copy(std::move(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy* c; c = new Copy(to_lvalue_ref(Copy(&f_eval))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 |   { Copy* c; c = new Copy(to_lvalue_ref(std::move(C))); } | 
 |   { Copy* c; c = new Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); }// expected-error {{is not a constant expression}} expected-note {{to a consteval}} | 
 | } | 
 |  | 
 | } // namespace special_ctor | 
 |  | 
 | namespace unevaluated { | 
 |  | 
 | template <typename T, typename U> struct is_same { static const bool value = false; }; | 
 | template <typename T> struct is_same<T, T> { static const bool value = true; }; | 
 |  | 
 | long f(); // expected-note {{declared here}} | 
 | auto consteval g(auto a) { | 
 |   return a; | 
 | } | 
 |  | 
 | auto e = g(f()); // expected-error {{is not a constant expression}} | 
 |                  // expected-note@-1 {{non-constexpr function 'f' cannot be used in a constant expression}} | 
 |  | 
 | using T = decltype(g(f())); | 
 | static_assert(is_same<long, T>::value); | 
 |  | 
 | } // namespace unevaluated | 
 |  | 
 | namespace value_dependent { | 
 |  | 
 | consteval int foo(int x) { | 
 |   return x; | 
 | } | 
 |  | 
 | template <int X> constexpr int bar() { | 
 |   // Previously this call was rejected as value-dependent constant expressions | 
 |   // can't be immediately evaluated. Now we show that we don't immediately | 
 |   // evaluate them until they are instantiated. | 
 |   return foo(X); | 
 | } | 
 |  | 
 | template <typename T> constexpr int baz() { | 
 |   constexpr int t = sizeof(T); | 
 |   // Previously this call was rejected as `t` is value-dependent and its value | 
 |   // is unknown until the function is instantiated. Now we show that we don't | 
 |   // reject such calls. | 
 |   return foo(t); | 
 | } | 
 |  | 
 | static_assert(bar<15>() == 15); | 
 | static_assert(baz<int>() == sizeof(int)); | 
 | } // namespace value_dependent | 
 |  | 
 | // https://github.com/llvm/llvm-project/issues/55601 | 
 | namespace issue_55601 { | 
 | template<typename T> | 
 | class Bar { | 
 |   consteval static T x() { return 5; }  // expected-note {{non-constexpr constructor 'derp' cannot be used in a constant expression}} | 
 |  public: | 
 |   Bar() : a(x()) {} // expected-error {{call to consteval function 'issue_55601::Bar<issue_55601::derp>::x' is not a constant expression}} | 
 |                     // expected-error@-1 {{call to consteval function 'issue_55601::derp::operator int' is not a constant expression}} | 
 |                     // expected-note@-2 {{in call to 'x()'}} | 
 |                     // expected-note@-3 {{non-literal type 'issue_55601::derp' cannot be used in a constant expression}} | 
 |  private: | 
 |   int a; | 
 | }; | 
 | Bar<int> f; | 
 | Bar<float> g; | 
 |  | 
 | struct derp { | 
 |   // Can't be used in a constant expression | 
 |   derp(int); // expected-note {{declared here}} | 
 |   consteval operator int() const { return 5; } | 
 | }; | 
 | Bar<derp> a; // expected-note {{in instantiation of member function 'issue_55601::Bar<issue_55601::derp>::Bar' requested here}} | 
 |  | 
 | struct constantDerp { | 
 |   // Can be used in a constant expression. | 
 |   consteval constantDerp(int) {} | 
 |   consteval operator int() const { return 5; } | 
 | }; | 
 | Bar<constantDerp> b; | 
 |  | 
 | } // namespace issue_55601 | 
 |  | 
 | namespace default_argument { | 
 |  | 
 | // Previously calls of consteval functions in default arguments were rejected. | 
 | // Now we show that we don't reject such calls. | 
 | consteval int foo() { return 1; } | 
 | consteval int bar(int i = foo()) { return i * i; } | 
 |  | 
 | struct Test1 { | 
 |   Test1(int i = bar(13)) {} | 
 |   void v(int i = bar(13) * 2 + bar(15)) {} | 
 | }; | 
 | Test1 t1; | 
 |  | 
 | struct Test2 { | 
 |   constexpr Test2(int i = bar()) {} | 
 |   constexpr void v(int i = bar(bar(bar(foo())))) {} | 
 | }; | 
 | Test2 t2; | 
 |  | 
 | } // namespace default_argument | 
 |  | 
 | namespace PR50779 { | 
 | struct derp { | 
 |   int b = 0; | 
 | }; | 
 |  | 
 | constexpr derp d; | 
 |  | 
 | struct test { | 
 |   consteval int operator[](int i) const { return {}; } | 
 |   consteval const derp * operator->() const { return &d; } | 
 |   consteval int f() const { return 12; } // expected-note 2{{declared here}} | 
 | }; | 
 |  | 
 | constexpr test a; | 
 |  | 
 | // We previously rejected both of these overloaded operators as taking the | 
 | // address of a consteval function outside of an immediate context, but we | 
 | // accepted direct calls to the overloaded operator. Now we show that we accept | 
 | // both forms. | 
 | constexpr int s = a.operator[](1); | 
 | constexpr int t = a[1]; | 
 | constexpr int u = a.operator->()->b; | 
 | constexpr int v = a->b; | 
 | // FIXME: I believe this case should work, but we currently reject. | 
 | constexpr int w = (a.*&test::f)(); // expected-error {{cannot take address of consteval function 'f' outside of an immediate invocation}} | 
 | constexpr int x = a.f(); | 
 |  | 
 | // Show that we reject when not in an immediate context. | 
 | int w2 = (a.*&test::f)(); // expected-error {{cannot take address of consteval function 'f' outside of an immediate invocation}} | 
 | } | 
 |  | 
 | namespace PR48235 { | 
 | consteval int d() { | 
 |   return 1; | 
 | } | 
 |  | 
 | struct A { | 
 |   consteval int a() const { return 1; } | 
 |  | 
 |   void b() { | 
 |     this->a() + d(); // expected-error {{call to consteval function 'PR48235::A::a' is not a constant expression}} \ | 
 |                      // expected-note {{use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}} | 
 |   } | 
 |  | 
 |   void c() { | 
 |     a() + d(); // expected-error {{call to consteval function 'PR48235::A::a' is not a constant expression}} \ | 
 |                // expected-note {{use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}} | 
 |   } | 
 | }; | 
 | } // PR48235 | 
 |  | 
 | namespace NamespaceScopeConsteval { | 
 | struct S { | 
 |   int Val; // expected-note {{subobject declared here}} | 
 |   consteval S() {} | 
 | }; | 
 |  | 
 | S s1; // expected-error {{call to consteval function 'NamespaceScopeConsteval::S::S' is not a constant expression}} \ | 
 |          expected-note {{subobject 'Val' is not initialized}} | 
 |  | 
 | template <typename Ty> | 
 | struct T { | 
 |   Ty Val; // expected-note {{subobject declared here}} | 
 |   consteval T() {} | 
 | }; | 
 |  | 
 | T<int> t; // expected-error {{call to consteval function 'NamespaceScopeConsteval::T<int>::T' is not a constant expression}} \ | 
 |              expected-note {{subobject 'Val' is not initialized}} | 
 |  | 
 | } // namespace NamespaceScopeConsteval | 
 |  | 
 | namespace Issue54578 { | 
 | // We expect the user-defined literal to be resovled entirely at compile time | 
 | // despite being instantiated through a template. | 
 | inline consteval unsigned char operator""_UC(const unsigned long long n) { | 
 |   return static_cast<unsigned char>(n); | 
 | } | 
 |  | 
 | inline constexpr char f1(const auto octet) { | 
 |   return 4_UC; | 
 | } | 
 |  | 
 | template <typename Ty> | 
 | inline constexpr char f2(const Ty octet) { | 
 |   return 4_UC; | 
 | } | 
 |  | 
 | void test() { | 
 |   static_assert(f1('a') == 4); | 
 |   static_assert(f2('a') == 4); | 
 |   constexpr int c = f1('a') + f2('a'); | 
 |   static_assert(c == 8); | 
 | } | 
 | } | 
 |  | 
 | namespace defaulted_special_member_template { | 
 | template <typename T> | 
 | struct default_ctor { | 
 |   T data; | 
 |   consteval default_ctor() = default; // expected-note {{non-constexpr constructor 'foo' cannot be used in a constant expression}} | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct copy { | 
 |   T data; | 
 |  | 
 |   consteval copy(const copy &) = default;            // expected-note {{non-constexpr constructor 'foo' cannot be used in a constant expression}} | 
 |   consteval copy &operator=(const copy &) = default; // expected-note {{non-constexpr function 'operator=' cannot be used in a constant expression}} | 
 |   copy() = default; | 
 | }; | 
 |  | 
 | template <typename T> | 
 | struct move { | 
 |   T data; | 
 |  | 
 |   consteval move(move &&) = default;            // expected-note {{non-constexpr constructor 'foo' cannot be used in a constant expression}} | 
 |   consteval move &operator=(move &&) = default; // expected-note {{non-constexpr function 'operator=' cannot be used in a constant expression}} | 
 |   move() = default; | 
 | }; | 
 |  | 
 | struct foo { | 
 |   foo() {}            // expected-note {{declared here}} | 
 |   foo(const foo &) {} // expected-note {{declared here}} | 
 |   foo(foo &&) {}      // expected-note {{declared here}} | 
 |  | 
 |   foo& operator=(const foo &) { return *this; } // expected-note {{declared here}} | 
 |   foo& operator=(foo &&) { return *this; }      // expected-note {{declared here}} | 
 | }; | 
 |  | 
 | void func() { | 
 |   default_ctor<foo> fail0; // expected-error {{call to consteval function 'defaulted_special_member_template::default_ctor<defaulted_special_member_template::foo>::default_ctor' is not a constant expression}} \ | 
 |                               expected-note {{in call to 'default_ctor()'}} | 
 |  | 
 |   copy<foo> good0; | 
 |   copy<foo> fail1{good0}; // expected-error {{call to consteval function 'defaulted_special_member_template::copy<defaulted_special_member_template::foo>::copy' is not a constant expression}} \ | 
 |                              expected-note {{in call to 'copy(good0)'}} | 
 |   fail1 = good0;          // expected-error {{call to consteval function 'defaulted_special_member_template::copy<defaulted_special_member_template::foo>::operator=' is not a constant expression}} \ | 
 |                              expected-note {{in call to 'fail1.operator=(good0)'}} | 
 |  | 
 |   move<foo> good1; | 
 |   move<foo> fail2{static_cast<move<foo>&&>(good1)}; // expected-error {{call to consteval function 'defaulted_special_member_template::move<defaulted_special_member_template::foo>::move' is not a constant expression}} \ | 
 |                                                        expected-note {{in call to 'move(good1)'}} | 
 |   fail2 = static_cast<move<foo>&&>(good1);          // expected-error {{call to consteval function 'defaulted_special_member_template::move<defaulted_special_member_template::foo>::operator=' is not a constant expression}} \ | 
 |                                                        expected-note {{in call to 'fail2.operator=(good1)'}} | 
 | } | 
 | } // namespace defaulted_special_member_template | 
 |  | 
 | namespace multiple_default_constructors { | 
 | struct Foo { | 
 |   Foo() {} // expected-note {{declared here}} | 
 | }; | 
 | struct Bar { | 
 |   Bar() = default; | 
 | }; | 
 | struct Baz { | 
 |   consteval Baz() {} | 
 | }; | 
 |  | 
 | template <typename T, unsigned N> | 
 | struct S { | 
 |   T data; | 
 |   S() requires (N==1) = default; | 
 |   // This cannot be used in constexpr context. | 
 |   S() requires (N==2) {}  // expected-note {{declared here}} | 
 |   consteval S() requires (N==3) = default;  // expected-note {{non-constexpr constructor 'Foo' cannot be used in a constant expression}} | 
 | }; | 
 |  | 
 | void func() { | 
 |   // Explicitly defaulted constructor. | 
 |   S<Foo, 1> s1; | 
 |   S<Bar, 1> s2; | 
 |   // User provided constructor. | 
 |   S<Foo, 2> s3; | 
 |   S<Bar, 2> s4; | 
 |   // Consteval explicitly defaulted constructor. | 
 |   S<Foo, 3> s5; // expected-error {{call to consteval function 'multiple_default_constructors::S<multiple_default_constructors::Foo, 3>::S' is not a constant expression}} \ | 
 |                    expected-note {{in call to 'S()'}} | 
 |   S<Bar, 3> s6; | 
 |   S<Baz, 3> s7; | 
 | } | 
 |  | 
 | consteval int aConstevalFunction() { // expected-error {{consteval function never produces a constant expression}} | 
 |   // Defaulted default constructors are implicitly consteval. | 
 |   S<Bar, 1> s1; | 
 |  | 
 |   S<Baz, 2> s4; // expected-note {{non-constexpr constructor 'S' cannot be used in a constant expression}} | 
 |  | 
 |   S<Bar, 3> s2; | 
 |   S<Baz, 3> s3; | 
 |   return 0; | 
 | } | 
 |  | 
 | } // namespace multiple_default_constructors | 
 |  | 
 | namespace GH50055 { | 
 | enum E {e1=0, e2=1}; | 
 | consteval int testDefaultArgForParam(E eParam = (E)-1) { | 
 | // expected-note@-1 {{integer value -1 is outside the valid range of values [0, 1] for the enumeration type 'E'}} | 
 |   return (int)eParam; | 
 | } | 
 |  | 
 | int test() { | 
 |   return testDefaultArgForParam() + testDefaultArgForParam((E)1); | 
 |   // expected-error@-1 {{call to consteval function 'GH50055::testDefaultArgForParam' is not a constant expression}} | 
 | } | 
 | } | 
 |  | 
 | namespace GH51182 { | 
 | // Nested consteval function. | 
 | consteval int f(int v) { | 
 |   return v; | 
 | } | 
 |  | 
 | template <typename T> | 
 | consteval int g(T a) { | 
 |   // An immediate function context. | 
 |   int n = f(a); | 
 |   return n; | 
 | } | 
 | static_assert(g(100) == 100); | 
 | // -------------------------------------- | 
 | template <typename T> | 
 | consteval T max(const T& a, const T& b) { | 
 |     return (a > b) ? a : b; | 
 | } | 
 | template <typename T> | 
 | consteval T mid(const T& a, const T& b, const T& c) { | 
 |     T m = max(max(a, b), c); | 
 |     if (m == a) | 
 |         return max(b, c); | 
 |     if (m == b) | 
 |         return max(a, c); | 
 |     return max(a, b); | 
 | } | 
 | static_assert(max(1,2)==2); | 
 | static_assert(mid(1,2,3)==2); | 
 | } // namespace GH51182 | 
 |  | 
 | // https://github.com/llvm/llvm-project/issues/56183 | 
 | namespace GH56183 { | 
 | consteval auto Foo(auto c) { return c; } | 
 | consteval auto Bar(auto f) { return f(); } | 
 | void test() { | 
 |   constexpr auto x = Foo(Bar([] { return 'a'; })); | 
 |   static_assert(x == 'a'); | 
 | } | 
 | }  // namespace GH56183 | 
 |  | 
 | // https://github.com/llvm/llvm-project/issues/51695 | 
 | namespace GH51695 { | 
 | // Original ======================================== | 
 | template <typename T> | 
 | struct type_t {}; | 
 |  | 
 | template <typename...> | 
 | struct list_t {}; | 
 |  | 
 | template <typename T, typename... Ts> | 
 | consteval auto pop_front(list_t<T, Ts...>) -> auto { | 
 |   return list_t<Ts...>{}; | 
 | } | 
 |  | 
 | template <typename... Ts, typename F> | 
 | consteval auto apply(list_t<Ts...>, F fn) -> auto { | 
 |   return fn(type_t<Ts>{}...); | 
 | } | 
 |  | 
 | void test1() { | 
 |   constexpr auto x = apply(pop_front(list_t<char, char>{}), | 
 |                             []<typename... Us>(type_t<Us>...) { return 42; }); | 
 |   static_assert(x == 42); | 
 | } | 
 | // Reduced 1 ======================================== | 
 | consteval bool zero() { return false; } | 
 |  | 
 | template <typename F> | 
 | consteval bool foo(bool, F f) { | 
 |   return f(); | 
 | } | 
 |  | 
 | void test2() { | 
 |   constexpr auto x = foo(zero(), []() { return true; }); | 
 |   static_assert(x); | 
 | } | 
 |  | 
 | // Reduced 2 ======================================== | 
 | template <typename F> | 
 | consteval auto bar(F f) { return f;} | 
 |  | 
 | void test3() { | 
 |   constexpr auto t1 = bar(bar(bar(bar([]() { return true; }))))(); | 
 |   static_assert(t1); | 
 |  | 
 |   int a = 1; // expected-note {{declared here}} | 
 |   auto t2 = bar(bar(bar(bar([=]() { return a; }))))(); // expected-error-re {{call to consteval function 'GH51695::bar<(lambda at {{.*}})>' is not a constant expression}} | 
 |   // expected-note@-1 {{read of non-const variable 'a' is not allowed in a constant expression}} | 
 |  | 
 |   constexpr auto t3 = bar(bar([x=bar(42)]() { return x; }))(); | 
 |   static_assert(t3==42); | 
 |   constexpr auto t4 = bar(bar([x=bar(42)]() consteval { return x; }))(); | 
 |   static_assert(t4==42); | 
 | } | 
 |  | 
 | }  // namespace GH51695 | 
 |  | 
 | // https://github.com/llvm/llvm-project/issues/50455 | 
 | namespace GH50455 { | 
 | void f() { | 
 |   []() consteval { int i{}; }(); | 
 |   []() consteval { int i{}; ++i; }(); | 
 | } | 
 | void g() { | 
 |   (void)[](int i) consteval { return i; }(0); | 
 |   (void)[](int i) consteval { return i; }(0); | 
 | } | 
 | }  // namespace GH50455 | 
 |  | 
 | namespace GH58302 { | 
 | struct A { | 
 |    consteval A(){} | 
 |    consteval operator int() { return 1;} | 
 | }; | 
 |  | 
 | int f() { | 
 |    int x = A{}; | 
 | } | 
 | } | 
 |  | 
 | namespace GH57682 { | 
 | void test() { | 
 |   constexpr auto l1 = []() consteval { // expected-error {{cannot take address of consteval call operator of '(lambda at}} \ | 
 |                                        // expected-note  2{{declared here}} | 
 |         return 3; | 
 |   }; | 
 |   constexpr int (*f1)(void) = l1; // expected-error {{constexpr variable 'f1' must be initialized by a constant expression}} \ | 
 |                                   // expected-note  {{pointer to a consteval declaration is not a constant expression}} | 
 |  | 
 |  | 
 |   constexpr auto lstatic = []() static consteval { // expected-error {{cannot take address of consteval call operator of '(lambda at}} \ | 
 |                                        // expected-note  2{{declared here}} \ | 
 |                                        // expected-warning {{extension}} | 
 |         return 3; | 
 |   }; | 
 |   constexpr int (*f2)(void) = lstatic; // expected-error {{constexpr variable 'f2' must be initialized by a constant expression}} \ | 
 |                                        // expected-note  {{pointer to a consteval declaration is not a constant expression}} | 
 |  | 
 |   int (*f3)(void) = []() consteval { return 3; };  // expected-error {{cannot take address of consteval call operator of '(lambda at}} \ | 
 |                                                    // expected-note {{declared here}} | 
 | } | 
 |  | 
 | consteval void consteval_test() { | 
 |   constexpr auto l1 = []() consteval { return 3; }; | 
 |  | 
 |   int (*f1)(void) = l1;  // ok | 
 | } | 
 | } | 
 |  | 
 | namespace GH60286 { | 
 |  | 
 | struct A { | 
 |   int i = 0; | 
 |  | 
 |   consteval A() {} | 
 |   A(const A&) { i = 1; } | 
 |   consteval int f() { return i; } | 
 | }; | 
 |  | 
 | constexpr auto B = A{A{}}.f(); | 
 | static_assert(B == 0); | 
 |  | 
 | } | 
 |  | 
 | namespace GH58207 { | 
 | struct tester { | 
 |     consteval tester(const char* name) noexcept { } | 
 | }; | 
 | consteval const char* make_name(const char* name) { return name;} | 
 | consteval const char* pad(int P) { return "thestring"; } | 
 |  | 
 | int bad = 10; // expected-note 6{{declared here}} | 
 |  | 
 | tester glob1(make_name("glob1")); | 
 | tester glob2(make_name("glob2")); | 
 | constexpr tester cglob(make_name("cglob")); | 
 | tester paddedglob(make_name(pad(bad))); // expected-error {{call to consteval function 'GH58207::tester::tester' is not a constant expression}} \ | 
 |                                         // expected-note {{read of non-const variable 'bad' is not allowed in a constant expression}} | 
 |  | 
 | constexpr tester glob3 = { make_name("glob3") }; | 
 | constexpr tester glob4 = { make_name(pad(bad)) }; // expected-error {{call to consteval function 'GH58207::tester::tester' is not a constant expression}} \ | 
 |                                                   // expected-error {{constexpr variable 'glob4' must be initialized by a constant expression}} \ | 
 |                                                   // expected-note 2{{read of non-const variable 'bad' is not allowed in a constant expression}} | 
 |  | 
 | auto V = make_name(pad(3)); | 
 | auto V1 = make_name(pad(bad)); // expected-error {{call to consteval function 'GH58207::make_name' is not a constant expression}} \ | 
 |                                // expected-note {{read of non-const variable 'bad' is not allowed in a constant expression}} | 
 |  | 
 |  | 
 | void foo() { | 
 |   static tester loc1(make_name("loc1")); | 
 |   static constexpr tester loc2(make_name("loc2")); | 
 |   static tester paddedloc(make_name(pad(bad))); // expected-error {{call to consteval function 'GH58207::tester::tester' is not a constant expression}} \ | 
 |                                                 // expected-note {{read of non-const variable 'bad' is not allowed in a constant expression}} | 
 | } | 
 |  | 
 | void bar() { | 
 |   static tester paddedloc(make_name(pad(bad))); // expected-error {{call to consteval function 'GH58207::tester::tester' is not a constant expression}} \ | 
 |                                                 // expected-note {{read of non-const variable 'bad' is not allowed in a constant expression}} | 
 | } | 
 | } | 
 |  | 
 | namespace GH64949 { | 
 | struct f { | 
 |   int g; // expected-note 2{{subobject declared here}} | 
 |   constexpr ~f() {} | 
 | }; | 
 | class h { | 
 |  | 
 | public: | 
 |   consteval h(char *) {} | 
 |   consteval operator int() const { return 1; } | 
 |   f i; | 
 | }; | 
 |  | 
 | void test() { (int)h{nullptr}; } | 
 | // expected-error@-1 {{call to consteval function 'GH64949::h::h' is not a constant expression}} | 
 | // expected-note@-2 {{subobject 'g' is not initialized}} | 
 |  | 
 | int  test2() { return h{nullptr}; } | 
 | // expected-error@-1 {{call to consteval function 'GH64949::h::h' is not a constant expression}} | 
 | // expected-note@-2 {{subobject 'g' is not initialized}} | 
 |  | 
 |  | 
 | } | 
 |  | 
 | namespace GH65985 { | 
 |  | 
 | int consteval operator""_foo(unsigned long long V) { | 
 |     return 0; | 
 | } | 
 | int consteval operator""_bar(unsigned long long V); // expected-note 4 {{here}} | 
 |  | 
 | int consteval f() { | 
 |   return 0; | 
 | } | 
 |  | 
 | int consteval g();  // expected-note 2 {{here}} | 
 |  | 
 |  | 
 | struct C { | 
 |     static const int a = 1_foo; | 
 |     static constexpr int b = 1_foo; | 
 |     static const int c = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \ | 
 |                                 // expected-note 2 {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ | 
 |                                 // expected-error {{in-class initializer for static data member is not a constant expression}} | 
 |  | 
 |     // FIXME: remove duplicate diagnostics | 
 |     static constexpr int d = 1_bar; // expected-error {{call to consteval function 'GH65985::operator""_bar' is not a constant expression}} \ | 
 |                                     // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} \ | 
 |                                     // expected-error {{constexpr variable 'd' must be initialized by a constant expression}}  \ | 
 |                                     // expected-note {{undefined function 'operator""_bar' cannot be used in a constant expression}} | 
 |  | 
 |     static const int e = f(); | 
 |     static const int f = g(); // expected-error {{call to consteval function 'GH65985::g' is not a constant expression}} \ | 
 |                               // expected-error {{in-class initializer for static data member is not a constant expression}} \ | 
 |                               // expected-note 2 {{undefined function 'g' cannot be used in a constant expression}} | 
 | }; | 
 |  | 
 | } | 
 |  | 
 | namespace GH66562 { | 
 |  | 
 | namespace ns | 
 | { | 
 |     consteval int foo(int x) { return 1; } // expected-note {{declared here}}  \ | 
 |                                            // expected-note {{passing argument to parameter 'x' here}} | 
 | } | 
 |  | 
 | template <class A> | 
 | struct T { | 
 |     static constexpr auto xx = ns::foo(A{}); // expected-error {{cannot take address of consteval function 'foo' outside of an immediate invocation}} \ | 
 |                                              // expected-error {{cannot initialize a parameter of type 'int' with an rvalue of type 'char *'}} | 
 | }; | 
 |  | 
 | template class T<char*>; // expected-note {{in instantiation}} | 
 |  | 
 | } | 
 |  | 
 | namespace GH65520 { | 
 |  | 
 | consteval int bar (int i) { if (i != 1) return 1/0; return 0; } | 
 | // expected-note@-1{{division by zero}} | 
 |  | 
 | void | 
 | g () | 
 | { | 
 |   int a_ok[bar(1)]; | 
 |   int a_err[bar(3)]; // expected-error {{call to consteval function 'GH65520::bar' is not a constant expression}} \ | 
 |                      // expected-note {{in call to 'bar(3)'}} | 
 | } | 
 |  | 
 | consteval int undefined(); // expected-note {{declared here}} | 
 |  | 
 | consteval void immediate() { | 
 |     int a [undefined()]; // expected-note  {{undefined function 'undefined' cannot be used in a constant expression}} \ | 
 |                          // expected-error {{call to consteval function 'GH65520::undefined' is not a constant expression}} \ | 
 |                          // expected-error {{variable of non-literal type 'int[undefined()]' cannot be defined in a constexpr function before C++23}} | 
 | } | 
 |  | 
 |  | 
 | } | 
 |  | 
 | namespace GH105558 { | 
 |  | 
 | consteval int* alloc() { return new int(0); } | 
 | consteval void f(int* p) { delete p; } | 
 | consteval void g1(int*&& p) { delete p; } | 
 | consteval void g2(const int* p) { delete p; } | 
 | consteval void g3(int*const& p) { delete p; } | 
 | struct X { | 
 |   int* p; | 
 |   explicit(false) constexpr X(int* p) : p(p) {} | 
 | }; | 
 | consteval void g4(X x) { delete x.p; } | 
 |  | 
 | void test() { | 
 |   f(alloc()); | 
 |   g1(alloc()); | 
 |   g2(alloc()); | 
 |   g3(alloc()); | 
 |   g4(alloc()); | 
 | } | 
 |  | 
 | } | 
 |  | 
 | // Test that we don't redundantly instantiate the friend declaration in | 
 | // RemoveNestedImmediateInvocation(). Otherwise, we would end up with spurious | 
 | // redefinition errors. | 
 | namespace GH107175 { | 
 |  | 
 | consteval void consteval_func() {} | 
 |  | 
 | template <auto> struct define_f { | 
 |   friend void foo() {} | 
 | }; | 
 |  | 
 | template <auto = [] {}> struct A {}; | 
 |  | 
 | struct B { | 
 |   template <auto T> consteval void func() { (void)define_f<T>{}; } | 
 | }; | 
 |  | 
 | int main() { | 
 |   B{}.func<A{}>(); | 
 |   consteval_func(); | 
 | } | 
 |  | 
 | } // namespace GH107175 | 
 |  | 
 | namespace GH137885 { | 
 |  | 
 | template <typename... P> struct A {}; | 
 |  | 
 | template <int N> | 
 | struct B { | 
 |   consteval B() {} | 
 |  | 
 |   template <typename... P> consteval operator A<P...>() const { | 
 |     static_assert(sizeof...(P) == N); | 
 |     return {}; | 
 |   } | 
 | }; | 
 |  | 
 | template <typename T> struct type_identity { | 
 |   using type = T; | 
 | }; | 
 |  | 
 | template <typename... P> | 
 | void foo(typename type_identity<A<P...>>::type a, P...) {} | 
 |  | 
 | void foo() { | 
 |   foo(B<0>()); | 
 |   foo(B<5>(), 1, 2, 3, 4, 5); | 
 | } | 
 |  | 
 | } | 
 |  | 
 | // https://github.com/llvm/llvm-project/issues/139160 | 
 | namespace GH139160{ | 
 |   // original test case taken from Github | 
 |   struct A {int x[1]; };  | 
 |   A f(); // expected-note {{declared here}} | 
 |   typedef int *t[]; | 
 |   consteval int* f(int* x) { return x; } | 
 |  | 
 |   int ** x = (t){f(f().x)}; // expected-error    {{call to consteval function 'GH139160::f' is not a constant expression}} | 
 |                             // expected-note@-1  {{non-constexpr function 'f' cannot be used in a constant expression}} | 
 |                             // expected-error@-2 {{initializer element is not a compile-time constant}}  | 
 |  | 
 |   struct B {int value, value_two;}; | 
 |   B make_struct() {return {10, 20};} // expected-note {{declared here}} | 
 |   consteval int get_value(B container) {return container.value;} | 
 |   B result = (B){10, get_value(make_struct())}; // expected-error {{initializer element is not a compile-time constant}}  | 
 |                                                 // expected-error@-1 {{call to consteval function 'GH139160::get_value' is not a constant expression}} | 
 |                                                 // expected-note@-2  {{non-constexpr function 'make_struct' cannot be used in a constant expression}} | 
 | }; | 
 |  | 
 |  |