brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.9 KiB · ff10424 Raw
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