648 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -Wno-unused-value %s -verify2// RUN: %clang_cc1 -std=c++2a -Wno-unused-value %s -verify -fexperimental-new-constant-interpreter3// RUN: %clang_cc1 -std=c++2b -Wno-unused-value %s -verify4// RUN: %clang_cc1 -std=c++2b -Wno-unused-value %s -verify -fexperimental-new-constant-interpreter5 6consteval int id(int i) { return i; }7constexpr char id(char c) { return c; }8 9template <typename T>10constexpr int f(T t) { // expected-note {{declared here}}11 return t + id(t); // expected-note 2{{'f<int>' is an immediate function because its body contains a call to a consteval function 'id' and that call is not a constant expression}}12}13 14namespace examples {15 16auto a = &f<char>; // ok, f<char> is not an immediate function17auto b = &f<int>; // expected-error {{cannot take address of immediate function 'f<int>' outside of an immediate invocation}}18 19static_assert(f(3) == 6); // ok20 21template <typename T>22constexpr int g(T t) { // g<int> is not an immediate function23 return t + id(42); // because id(42) is already a constant24}25 26template <typename T, typename F>27constexpr bool is_not(T t, F f) {28 return not f(t);29}30 31consteval bool is_even(int i) { return i % 2 == 0; }32 33static_assert(is_not(5, is_even));34 35int x = 0; // expected-note {{declared here}}36 37template <typename T>38constexpr T h(T t = id(x)) { // expected-note {{read of non-const variable 'x' is not allowed in a constant expression}} \39 // expected-note {{'hh<int>' is an immediate function because its body contains a call to a consteval function 'id' and that call is not a constant expression}}40 return t;41}42 43template <typename T>44constexpr T hh() { // hh<int> is an immediate function45 [[maybe_unused]] auto x = h<T>();46 return h<T>();47}48 49int i = hh<int>(); // expected-error {{call to immediate function 'examples::hh<int>' is not a constant expression}} \50 // expected-note {{in call to 'hh<int>()'}}51 52struct A {53 int x;54 int y = id(x);55};56 57template <typename T>58constexpr int k(int) {59 return A(42).y;60}61 62}63 64namespace nested {65 66template <typename T>67constexpr int fdupe(T t) {68 return id(t);69}70 71struct a {72 constexpr a(int) { }73};74 75a aa(fdupe<int>((f<int>(7))));76 77template <typename T>78constexpr int foo(T t); // expected-note {{declared here}}79 80a bb(f<int>(foo<int>(7))); // expected-error{{call to immediate function 'f<int>' is not a constant expression}} \81 // expected-note{{undefined function 'foo<int>' cannot be used in a constant expression}}82 83}84 85namespace e2{86template <typename T>87constexpr int f(T t);88auto a = &f<char>;89auto b = &f<int>;90}91 92namespace forward_declare_constexpr{93template <typename T>94constexpr int f(T t);95 96auto a = &f<char>;97auto b = &f<int>;98 99template <typename T>100constexpr int f(T t) {101 return id(0);102}103}104 105namespace forward_declare_consteval{106template <typename T>107constexpr int f(T t);108 109auto a = &f<char>;110auto b = &f<int>; // expected-error {{immediate function 'f<int>' used before it is defined}} \111 // expected-note {{in instantiation of function template specialization}}112 113template <typename T>114constexpr int f(T t) { // expected-note {{'f<int>' defined here}}115 return id(t); // expected-note {{'f<int>' is an immediate function because its body contains a call to a consteval function 'id' and that call is not a constant expression}}116}117}118 119namespace constructors {120consteval int f(int) {121 return 0;122}123struct S {124 constexpr S(auto i) {125 f(i);126 }127};128constexpr void g(auto i) {129 [[maybe_unused]] S s{i};130}131void test() {132 g(0);133}134}135 136namespace aggregate {137consteval int f(int);138struct S{139 int a = 0;140 int b = f(a);141};142 143constexpr bool test(auto i) {144 S s{i};145 return s.b == 2 *i;146}147consteval int f(int i) {148 return 2 * i;149}150 151void test() {152 static_assert(test(42));153}154 155}156 157namespace ConstevalConstructor{158int x = 0; // expected-note {{declared here}}159struct S {160 consteval S(int) {};161};162constexpr int g(auto t) {163 S s(t); // expected-note {{'g<int>' is an immediate function because its body contains a call to a consteval constructor 'S' and that call is not a constant expression}}164 return 0;165}166int i = g(x); // expected-error {{call to immediate function 'ConstevalConstructor::g<int>' is not a constant expression}} \167 // expected-note {{read of non-const variable 'x' is not allowed in a constant expression}}168}169 170 171 172namespace Aggregate {173consteval int f(int); // expected-note {{declared here}}174struct S {175 int x = f(42); // expected-note {{undefined function 'f' cannot be used in a constant expression}} \176 // expected-note {{'immediate<int>' is an immediate function because its body contains a call to a consteval function 'f' and that call is not a constant expression}}177};178 179constexpr S immediate(auto) {180 return S{};181}182 183void test_runtime() {184 (void)immediate(0); // expected-error {{call to immediate function 'Aggregate::immediate<int>' is not a constant expression}} \185 // expected-note {{in call to 'immediate<int>(0)'}}186}187consteval int f(int i) {188 return i;189}190consteval void test() {191 constexpr S s = immediate(0);192 static_assert(s.x == 42);193}194}195 196 197 198namespace GH63742 {199void side_effect(); // expected-note {{declared here}}200consteval int f(int x) {201 if (!x) side_effect(); // expected-note {{non-constexpr function 'side_effect' cannot be used in a constant expression}}202 return x;203}204struct SS {205 int y = f(1); // Ok206 int x = f(0); // expected-error {{call to consteval function 'GH63742::f' is not a constant expression}} \207 // expected-note {{declared here}} \208 // expected-note {{in call to 'f(0)'}}209 SS();210};211SS::SS(){} // expected-note {{in the default initializer of 'x'}}212 213consteval int f2(int x) {214 if (!__builtin_is_constant_evaluated()) side_effect();215 return x;216}217struct S2 {218 int x = f2(0);219 constexpr S2();220};221 222constexpr S2::S2(){}223S2 s = {};224constinit S2 s2 = {};225 226struct S3 {227 int x = f2(0);228 S3();229};230S3::S3(){}231 232}233 234namespace Defaulted {235consteval int f(int x);236struct SS {237 int x = f(0);238 SS() = default;239};240}241 242namespace DefaultedUse{243consteval int f(int x); // expected-note {{declared here}}244struct SS {245 int a = sizeof(f(0)); // Ok246 int x = f(0); // expected-note {{undefined function 'f' cannot be used in a constant expression}}247 248 SS() = default; // expected-note {{'SS' is an immediate constructor because the default initializer of 'x' contains a call to a consteval function 'f' and that call is not a constant expression}}249};250 251void test() {252 [[maybe_unused]] SS s; // expected-error {{call to immediate function 'DefaultedUse::SS::SS' is not a constant expression}} \253 // expected-note {{in call to 'SS()'}}254}255}256 257namespace UserDefinedConstructors {258consteval int f(int x) {259 return x;260}261extern int NonConst; // expected-note 2{{declared here}}262 263struct ConstevalCtr {264 int y;265 int x = f(y);266 consteval ConstevalCtr(int yy)267 : y(f(yy)) {}268};269 270ConstevalCtr c1(1);271ConstevalCtr c2(NonConst);272// expected-error@-1 {{call to consteval function 'UserDefinedConstructors::ConstevalCtr::ConstevalCtr' is not a constant expression}} \273// expected-note@-1 {{read of non-const variable 'NonConst' is not allowed in a constant expression}}274 275struct ImmediateEscalating {276 int y;277 int x = f(y);278 template<typename T>279 constexpr ImmediateEscalating(T yy) // expected-note {{ImmediateEscalating<int>' is an immediate constructor because the initializer of 'y' contains a call to a consteval function 'f' and that call is not a constant expression}}280 : y(f(yy)) {}281};282 283ImmediateEscalating c3(1);284ImmediateEscalating c4(NonConst);285// expected-error@-1 {{call to immediate function 'UserDefinedConstructors::ImmediateEscalating::ImmediateEscalating<int>' is not a constant expression}} \286// expected-note@-1 {{read of non-const variable 'NonConst' is not allowed in a constant expression}}287 288 289struct NonEscalating {290 int y;291 int x = f(this->y); // expected-error {{call to consteval function 'UserDefinedConstructors::f' is not a constant expression}} \292 // expected-note {{declared here}} \293 // expected-note {{use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}294 constexpr NonEscalating(int yy) : y(yy) {} // expected-note {{in the default initializer of 'x'}}295};296NonEscalating s = {1};297 298}299 300namespace AggregateInit {301 302consteval int f(int x) {303 return x;304}305 306struct S {307 int i;308 int j = f(i);309};310 311constexpr S test(auto) {312 return {};313}314 315S s = test(0);316 317}318 319namespace GlobalAggregateInit {320 321consteval int f(int x) {322 return x;323}324 325struct S {326 int i;327 int j = f(i); // expected-error {{call to consteval function 'GlobalAggregateInit::f' is not a constant expression}} \328 // expected-note {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}} \329 // expected-note {{declared here}}330};331 332S s(0); // expected-note {{in the default initializer of 'j'}}333 334}335 336namespace GH65985 {337consteval int invalid(); // expected-note 2{{declared here}}338constexpr int escalating(auto) {339 return invalid();340 // expected-note@-1 {{'escalating<int>' is an immediate function because its body contains a call to a consteval function 'invalid' and that call is not a constant expression}}341 // expected-note@-2 2{{undefined function 'invalid' cannot be used in a constant expression}}342}343struct S {344 static constexpr int a = escalating(0); // expected-note 2{{in call to}}345 // expected-error@-1 {{call to immediate function 'GH65985::escalating<int>' is not a constant expression}}346 // expected-error@-2 {{constexpr variable 'a' must be initialized by a constant expression}}347};348 349}350 351namespace GH66324 {352 353consteval int allocate(); // expected-note 2{{declared here}}354 355struct _Vector_base {356 int b = allocate(); // expected-note 2{{undefined function 'allocate' cannot be used in a constant expression}} \357 // expected-error {{call to consteval function 'GH66324::allocate' is not a constant expression}} \358 // expected-note {{declared here}}359};360 361template <typename>362struct vector : _Vector_base {363 constexpr vector()364 // expected-note@-1 {{'vector' is an immediate constructor because its body contains a call to a consteval function 'allocate' and that call is not a constant expression}}365 : _Vector_base{} {} // expected-note {{in the default initializer of 'b'}}366};367 368vector<void> v{};369// expected-error@-1 {{call to immediate function 'GH66324::vector<void>::vector' is not a constant expression}}370// expected-note@-2 {{in call to 'vector()'}}371 372}373 374 375namespace GH82258 {376 377template <class R, class Pred>378constexpr auto none_of(R&& r, Pred pred) -> bool { return true; }379 380struct info { int value; };381consteval auto is_invalid(info i) -> bool { return false; }382constexpr info types[] = { {1}, {3}, {5}};383 384static_assert(none_of(385 types,386 +[](info i) consteval {387 return is_invalid(i);388 }389));390 391static_assert(none_of(392 types,393 []{394 return is_invalid;395 }()396));397 398}399 400#if __cplusplus >= 202302L401namespace lvalue_to_rvalue_init_from_heap {402 403struct S {404 int *value;405 constexpr S(int v) : value(new int {v}) {} // expected-note 2 {{heap allocation performed here}}406 constexpr ~S() { delete value; }407};408consteval S fn() { return S(5); }409int fn2() { return 2; } // expected-note {{declared here}}410 411constexpr int a = *fn().value;412constinit int b = *fn().value;413const int c = *fn().value;414int d = *fn().value;415 416constexpr int e = *fn().value + fn2(); // expected-error {{must be initialized by a constant expression}} \417 // expected-error {{call to consteval function 'lvalue_to_rvalue_init_from_heap::fn' is not a constant expression}} \418 // expected-note {{non-constexpr function 'fn2'}} \419 // expected-note {{pointer to heap-allocated object}}420 421int f = *fn().value + fn2(); // expected-error {{call to consteval function 'lvalue_to_rvalue_init_from_heap::fn' is not a constant expression}} \422 // expected-note {{pointer to heap-allocated object}}423}424#endif425 426 427#if __cplusplus >= 202302L428 429namespace GH91509 {430 431consteval int f(int) { return 0; }432 433template<typename T>434constexpr int g(int x) {435 if consteval {436 return f(x);437 }438 if !consteval {}439 else {440 return f(x);441 }442 return 1;443}444 445int h(int x) {446 return g<void>(x);447}448}449 450#endif451 452 453namespace GH91308 {454 constexpr void f(auto) {455 static_assert(false);456 }457 using R1 = decltype(&f<int>);458}459 460namespace GH94935 {461 462consteval void f(int) {}463consteval void undef(int); // expected-note {{declared here}}464 465template<typename T>466struct G {467 void g() {468 GH94935::f(T::fn());469 GH94935::f(T::undef2()); // expected-error {{call to consteval function 'GH94935::f' is not a constant expression}} \470 // expected-note {{undefined function 'undef2' cannot be used in a constant expression}}471 GH94935::undef(T::fn()); // expected-error {{call to consteval function 'GH94935::undef' is not a constant expression}} \472 // expected-note {{undefined function 'undef' cannot be used in a constant expression}}473 }474};475 476struct X {477 static consteval int fn() { return 0; }478 static consteval int undef2(); // expected-note {{declared here}}479 480};481 482void test() {483 G<X>{}.g(); // expected-note {{instantiation}}484}485 486 487template<typename T>488void g() {489 auto l = []{490 ::f(T::fn());491 };492}493 494struct Y {495 static int fn();496};497 498template void g<Y>();499 500}501 502namespace GH112677 {503 504class ConstEval {505 public:506 consteval ConstEval(int); // expected-note 2{{declared here}}507};508 509struct TemplateCtor {510 ConstEval val;511 template <class Anything = int> constexpr512 TemplateCtor(int arg) : val(arg) {} // expected-note {{undefined constructor 'ConstEval'}}513};514struct C : TemplateCtor {515 using TemplateCtor::TemplateCtor; // expected-note {{in call to 'TemplateCtor<int>(0)'}}516};517 518C c(0); // expected-note{{in implicit initialization for inherited constructor of 'C'}}519// expected-error@-1 {{call to immediate function 'GH112677::C::TemplateCtor' is not a constant expression}}520 521struct SimpleCtor { constexpr SimpleCtor(int) {}};522struct D : SimpleCtor {523 int y = 10;524 ConstEval x = y; // expected-note {{undefined constructor 'ConstEval'}}525 using SimpleCtor::SimpleCtor;526 //expected-note@-1 {{'SimpleCtor' is an immediate constructor because the default initializer of 'x' contains a call to a consteval constructor 'ConstEval' and that call is not a constant expression}}527};528 529D d(0); // expected-note {{in implicit initialization for inherited constructor of 'D'}}530// expected-error@-1 {{call to immediate function 'GH112677::D::SimpleCtor' is not a constant expression}}531 532}533 534namespace GH123405 {535 536consteval void fn() {}537 538template <typename>539constexpr auto tfn(int) {540 auto p = &fn; // expected-note {{'tfn<int>' is an immediate function because its body evaluates the address of a consteval function 'fn'}}541 return p;542}543 544void g() {545 int a; // expected-note {{declared here}}546 tfn<int>(a); // expected-error {{call to immediate function 'GH123405::tfn<int>' is not a constant expression}}\547 // expected-note {{read of non-const variable 'a' is not allowed in a constant expression}}548}549} // namespace GH123405550 551namespace GH118000 {552consteval int baz() { return 0;}553struct S {554 int mSize = baz();555};556 557consteval void bar() {558 S s;559}560 561void foo() {562 S s;563}564} // namespace GH118000565 566namespace GH119046 {567 568template <typename Cls> constexpr auto tfn(int) {569 return (unsigned long long)(&Cls::sfn);570 //expected-note@-1 {{'tfn<GH119046::S>' is an immediate function because its body evaluates the address of a consteval function 'sfn'}}571};572struct S { static consteval void sfn() {} };573 574int f() {575 int a = 0; // expected-note{{declared here}}576 return tfn<S>(a);577 //expected-error@-1 {{call to immediate function 'GH119046::tfn<GH119046::S>' is not a constant expression}}578 //expected-note@-2 {{read of non-const variable 'a' is not allowed in a constant expression}}579}580}581 582#if __cplusplus >= 202302L583namespace GH135281 {584 struct B {585 const void* p;586 consteval B() : p{this} {}587 };588 B b;589 B b2{};590 B &&b3{};591 void f() {592 static B b4;593 B b5; // expected-error {{call to consteval function 'GH135281::B::B' is not a constant expression}} \594 // expected-note {{pointer to temporary is not a constant expression}} \595 // expected-note {{temporary created here}}596 }597 template<typename T> T temp_var_uninit;598 template<typename T> T temp_var_brace_init{};599 B* b6 = &temp_var_uninit<B>;600 B* b7 = &temp_var_brace_init<B>;601 B* b8 = &temp_var_brace_init<B&&>;602 template<typename T> void f2() {603 static T b9;604 T b10; // expected-error {{call to consteval function 'GH135281::B::B' is not a constant expression}} \605 // expected-note {{pointer to temporary is not a constant expression}} \606 // expected-note {{temporary created here}}607 static B b11;608 B b12; // expected-error 2 {{call to consteval function 'GH135281::B::B' is not a constant expression}} \609 // expected-note 2 {{pointer to temporary is not a constant expression}} \610 // expected-note 2 {{temporary created here}}611 }612 void (*ff)() = f2<B>; // expected-note {{instantiation of function template specialization}}613}614#endif615 616namespace GH145776 {617 618void runtime_only() {}619consteval void comptime_only() {}620 621void fn() {622 []() {623 runtime_only();624 []() {625 &comptime_only;626 }();627 }();628}629 630}631 632 633namespace GH109096 {634consteval void undefined();635template <typename T>636struct scope_exit {637 T t;638 constexpr ~scope_exit() { t(); }639 // expected-error@-1 {{call to immediate function 'GH109096::(anonymous class)::operator()' is not a constant expression}} \640 // expected-note@-1 {{implicit use of 'this' pointer is only allowed within the evaluation}}641};642 643scope_exit guard( // expected-note {{in instantiation of member function}}644 []() { undefined(); }645);646 647}648