|  | // 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 3{{here}} | 
|  |  | 
|  | int consteval f() { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int consteval g();  // expected-note {{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 {{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  {{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 |