brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.1 KiB · 8194606 Raw
499 lines · cpp
1// UNSUPPORTED:  target={{.*}}-zos{{.*}}2// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -Wno-deprecated-volatile -verify=ref,ref20,all,all20 %s3// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -Wno-deprecated-volatile -verify=ref,ref23,all,all23 %s4// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -Wno-deprecated-volatile -verify=expected20,all,all20 %s -fexperimental-new-constant-interpreter5// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -Wno-deprecated-volatile -verify=expected23,all,all23 %s -fexperimental-new-constant-interpreter6 7 8#define assert_active(F)   if (!__builtin_is_within_lifetime(&F)) (1/0);9#define assert_inactive(F) if ( __builtin_is_within_lifetime(&F)) (1/0);10 11inline constexpr void* operator new(__SIZE_TYPE__, void* p) noexcept { return p; }12namespace std {13template<typename T, typename... Args>14constexpr T* construct_at(T* p, Args&&... args) { return ::new((void*)p) T(static_cast<Args&&>(args)...); }15}16 17constexpr int f(int n) {  // all20-error {{constexpr function never produces a constant expression}}18  static const int m = n; // all-note {{control flows through the definition of a static variable}} \19                          // all20-note {{control flows through the definition of a static variable}} \20                          // all20-warning {{is a C++23 extension}}21 22  return m;23}24static_assert(f(0) == 0, ""); // all-error {{not an integral constant expression}} \25                              // all-note {{in call to}}26 27constexpr int g(int n) {        // all20-error {{constexpr function never produces a constant expression}}28  thread_local const int m = n; // all-note {{control flows through the definition of a thread_local variable}} \29                                // all20-note {{control flows through the definition of a thread_local variable}} \30                                // all20-warning {{is a C++23 extension}}31  return m;32}33static_assert(g(0) == 0, ""); // all-error {{not an integral constant expression}} \34                              // all-note {{in call to}}35 36constexpr int c_thread_local(int n) { // all20-error {{constexpr function never produces a constant expression}}37  static _Thread_local int m = 0;     // all20-note 2{{control flows through the definition of a thread_local variable}} \38                                      // all23-note {{control flows through the definition of a thread_local variable}} \39                                      // all20-warning {{is a C++23 extension}}40  return m;41}42static_assert(c_thread_local(0) == 0, ""); // all-error {{not an integral constant expression}} \43                                           // all-note {{in call to}}44 45 46constexpr int gnu_thread_local(int n) { // all20-error {{constexpr function never produces a constant expression}}47  static __thread int m = 0;            // all20-note 2{{control flows through the definition of a thread_local variable}} \48                                        // all23-note {{control flows through the definition of a thread_local variable}} \49                                        // all20-warning {{is a C++23 extension}}50  return m;51}52static_assert(gnu_thread_local(0) == 0, ""); // all-error {{not an integral constant expression}} \53                                             // all-note {{in call to}}54 55constexpr int h(int n) {  // all20-error {{constexpr function never produces a constant expression}}56  static const int m = n; // all20-note {{control flows through the definition of a static variable}} \57                          // all20-warning {{is a C++23 extension}}58  return &m - &m;59}60 61constexpr int i(int n) {        // all20-error {{constexpr function never produces a constant expression}}62  thread_local const int m = n; // all20-note {{control flows through the definition of a thread_local variable}} \63                                // all20-warning {{is a C++23 extension}}64  return &m - &m;65}66 67constexpr int j(int n) {68  if (!n)69    return 0;70  static const int m = n; // ref20-warning {{is a C++23 extension}} \71                          // expected20-warning {{is a C++23 extension}}72  return m;73}74constexpr int j0 = j(0);75 76constexpr int k(int n) {77  if (!n)78    return 0;79  thread_local const int m = n; // ref20-warning {{is a C++23 extension}} \80                                // expected20-warning {{is a C++23 extension}}81 82  return m;83}84constexpr int k0 = k(0);85 86namespace ThreadLocalStore {87  thread_local int &&a = 0;88  void store() { a = 42; }89}90 91#if __cplusplus >= 202302L92constexpr int &b = b; // all-error {{must be initialized by a constant expression}} \93                      // all-note {{initializer of 'b' is not a constant expression}} \94                      // all-note {{declared here}}95#endif96 97namespace StaticLambdas {98  constexpr auto static_capture_constexpr() {99    char n = 'n';100    return [n] static { return n; }(); // expected23-error {{a static lambda cannot have any captures}} \101                                       // expected20-error {{a static lambda cannot have any captures}} \102                                       // expected20-warning {{are a C++23 extension}} \103                                       // expected20-warning {{is a C++23 extension}} \104                                       // ref23-error {{a static lambda cannot have any captures}} \105                                       // ref20-error {{a static lambda cannot have any captures}} \106                                       // ref20-warning {{are a C++23 extension}} \107                                       // ref20-warning {{is a C++23 extension}}108  }109  static_assert(static_capture_constexpr()); // expected23-error {{static assertion expression is not an integral constant expression}} \110                                             // expected20-error {{static assertion expression is not an integral constant expression}} \111                                             // ref23-error {{static assertion expression is not an integral constant expression}} \112                                             // ref20-error {{static assertion expression is not an integral constant expression}}113 114  constexpr auto capture_constexpr() {115    char n = 'n';116    return [n] { return n; }();117  }118  static_assert(capture_constexpr());119}120 121namespace StaticOperators {122  auto lstatic = []() static { return 3; };  // ref20-warning {{C++23 extension}} \123                                             // expected20-warning {{C++23 extension}}124  static_assert(lstatic() == 3, "");125  constexpr int (*f2)(void) = lstatic;126  static_assert(f2() == 3);127 128  struct S1 {129    constexpr S1() { // all20-error {{never produces a constant expression}}130      throw; // all-note {{not valid in a constant expression}} \131             // all20-note {{not valid in a constant expression}}132    }133    static constexpr int operator()() { return 3; } // ref20-warning {{C++23 extension}} \134                                                    // expected20-warning {{C++23 extension}}135  };136  static_assert(S1{}() == 3, ""); // all-error {{not an integral constant expression}} \137                                  // all-note {{in call to}}138 139 140 141}142 143int test_in_lambdas() {144  auto c = [](int n) constexpr {145    if (n == 0)146      return 0;147    else148      goto test; // all-note {{subexpression not valid in a constant expression}} \149                 // all20-warning {{use of this statement in a constexpr function is a C++23 extension}}150  test:151    return 1;152  };153  c(0);154  constexpr auto A = c(1); // all-error {{must be initialized by a constant expression}} \155                           // all-note {{in call to}}156  return 0;157}158 159/// PackIndexExpr.160template <auto... p>161struct check_ice {162    enum e {163        x = p...[0] // all-warning {{is a C++2c extension}}164    };165};166static_assert(check_ice<42>::x == 42);167 168 169namespace VirtualBases {170  namespace One {171    struct U { int n; };172    struct V : U { int n; };173    struct A : virtual V { int n; };174    struct Aa { int n; };175    struct B : virtual A, Aa {};176    struct C : virtual A, Aa {};177    struct D : B, C {};178 179    /// Calls the constructor of D.180    D d;181  }182 183#if __cplusplus >= 202302L184  struct VBase {};185  struct HasVBase : virtual VBase {}; // all23-note 1{{virtual base class declared here}}186  struct Derived : HasVBase {187    constexpr Derived() {} // all23-error {{constexpr constructor not allowed in struct with virtual base class}}188  };189  template<typename T> struct DerivedFromVBase : T {190    constexpr DerivedFromVBase();191  };192  constexpr int f(DerivedFromVBase<HasVBase>) {}193  template<typename T> constexpr DerivedFromVBase<T>::DerivedFromVBase() : T() {}194  constexpr int nVBase = (DerivedFromVBase<HasVBase>(), 0); // all23-error {{constant expression}} \195                                                            // all23-note {{cannot construct object of type 'DerivedFromVBase<VirtualBases::HasVBase>' with virtual base class in a constant expression}}196#endif197}198 199namespace LabelGoto {200  constexpr int foo() { // all20-error {{never produces a constant expression}}201    a: // all20-warning {{use of this statement in a constexpr function is a C++23 extension}}202    goto a; // all20-note 2{{subexpression not valid in a constant expression}} \203            // ref23-note {{subexpression not valid in a constant expression}} \204            // expected23-note {{subexpression not valid in a constant expression}}205 206    return 1;207  }208  static_assert(foo() == 1, ""); // all-error {{not an integral constant expression}} \209                                 // all-note {{in call to}}210}211 212namespace ExplicitLambdaThis {213  constexpr auto f = [x = 3]<typename Self>(this Self self) { // all20-error {{explicit object parameters are incompatible with C++ standards before C++2b}}214      return x;215  };216  static_assert(f());217}218 219namespace std {220  struct strong_ordering {221    int n;222    constexpr operator int() const { return n; }223    static const strong_ordering less, equal, greater;224  };225  constexpr strong_ordering strong_ordering::less = {-1};226  constexpr strong_ordering strong_ordering::equal = {0};227  constexpr strong_ordering strong_ordering::greater = {1};228}229 230namespace UndefinedThreeWay {231  struct A {232    friend constexpr std::strong_ordering operator<=>(const A&, const A&) = default; // all-note {{declared here}}233  };234 235  constexpr std::strong_ordering operator<=>(const A&, const A&) noexcept;236  constexpr std::strong_ordering (*test_a_threeway)(const A&, const A&) = &operator<=>;237  static_assert(!(*test_a_threeway)(A(), A())); // all-error {{static assertion expression is not an integral constant expression}} \238                                                // all-note {{undefined function 'operator<=>' cannot be used in a constant expression}}239}240 241/// FIXME: The new interpreter is missing the "initializer of q is not a constant expression" diagnostics.a242/// That's because the cast from void* to int* is considered fine, but diagnosed. So we don't consider243/// q to be uninitialized.244namespace VoidCast {245  constexpr void* p = nullptr;246  constexpr int* q = static_cast<int*>(p); // all-error {{must be initialized by a constant expression}} \247                                           // all-note {{cast from 'void *' is not allowed in a constant expression}} \248                                           // ref-note {{declared here}}249  static_assert(q == nullptr); // ref-error {{not an integral constant expression}} \250                               // ref-note {{initializer of 'q' is not a constant expression}}251}252 253namespace ExplicitLambdaInstancePointer {254  struct C {255      constexpr C(auto) { }256  };257  void foo() {258      constexpr auto b = [](this C) { return 1; }; // all20-error {{explicit object parameters are incompatible with C++ standards before C++2b}}259      constexpr int (*fp)(C) = b;260      static_assert(fp(1) == 1, "");261  }262}263 264namespace TwosComplementShifts {265  using uint32 = __UINT32_TYPE__;266  using int32 = __INT32_TYPE__;267  static_assert(uint32(int32(0x1234) << 16) == 0x12340000);268  static_assert(uint32(int32(0x1234) << 19) == 0x91a00000);269  static_assert(uint32(int32(0x1234) << 20) == 0x23400000);270  static_assert(uint32(int32(0x1234) << 24) == 0x34000000);271  static_assert(uint32(int32(-1) << 31) == 0x80000000);272 273  static_assert(-2 >> 1 == -1);274  static_assert(-3 >> 1 == -2);275  static_assert(-7 >> 1 == -4);276}277 278namespace AnonUnionDtor {279  struct A {280    A ();281    ~A();282  };283 284  template <class T>285  struct opt286  {287    union {288      char c;289      T data;290    };291 292    constexpr opt() {}293 294    constexpr ~opt()  {295     if (engaged)296       data.~T();297   }298 299    bool engaged = false;300  };301 302  consteval void foo() {303    opt<A> a;304  }305 306  void bar() { foo(); }307}308 309/// FIXME: The two interpreters disagree about there to diagnose the non-constexpr destructor call.310namespace NonLiteralDtorInParam {311  class NonLiteral { // all20-note {{is not an aggregate and has no constexpr constructors other than copy or move constructors}}312  public:313    NonLiteral() {}314    ~NonLiteral() {} // all23-note {{declared here}}315  };316  constexpr int F2(NonLiteral N) { // all20-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} \317                                   // all23-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}}318    return 8;319  }320 321 322  void test() {323    NonLiteral L;324    constexpr auto D = F2(L); // all23-error {{must be initialized by a constant expression}}325  }326}327 328namespace ZeroSizedArray {329  struct S {330    constexpr ~S() {331    }332  };333  constexpr int foo() {334    S s[0];335    return 1;336  }337  static_assert(foo() == 1);338}339namespace VoidCast {340  constexpr int a = 12;341  constexpr const int *b = &a;342  constexpr int *f = (int*)(void*)b; // all-error {{must be initialized by a constant expression}} \343                                     // all-note {{cast from 'void *' is not allowed in a constant expression}}344}345 346#if __cplusplus >= 202302L347namespace NestedUnions {348  consteval bool test_nested() {349    union {350      union { int i; char c; } u;351      long l;352    };353    std::construct_at(&l);354    assert_active(l);355    assert_inactive(u);356 357    std::construct_at(&u);358    assert_active(u);359    assert_inactive(l);360    assert_active(u.i);361    assert_inactive(u.c);362 363    std::construct_at(&u.i);364    assert_active(u);365    assert_inactive(u.c);366 367 368    std::construct_at(&u.c);369    assert_active(u);370    assert_inactive(u.i);371    assert_active(u.c);372    assert_inactive(l);373    return true;374  }375  static_assert(test_nested());376}377 378namespace UnionMemberCallDiags {379  struct A { int n; };380  struct B { A a; };381  constexpr A a = (A() = B().a);382 383  union C {384    int n;385    A a;386  };387 388  constexpr bool g() {389    C c = {.n = 1};390    c.a.operator=(B{2}.a); // all-note {{member call on member 'a' of union with active member 'n' is not allowed in a constant expression}}391    return c.a.n == 2;392  }393  static_assert(g()); // all-error {{not an integral constant expression}} \394                      // all-note {{in call to}}395}396#endif397 398namespace VolatileWrites {399  constexpr void test1() {// all20-error {{never produces a constant expression}}400    int k;401    volatile int &m = k;402    m = 10; // all20-note {{assignment to volatile-qualified type 'volatile int'}}403  }404 405  constexpr void test2() { // all20-error {{never produces a constant expression}}406    volatile int k = 12;407 408    k = 13; // all20-note {{assignment to volatile-qualified type 'volatile int'}}409  }410 411  constexpr void test3() { // all20-error {{never produces a constant expression}}412    volatile int k = 12; // all20-note {{volatile object declared here}}413 414    *((int *)&k) = 13; // all20-note {{assignment to volatile object 'k' is not allowed in a constant expression}}415  }416 417  constexpr void test4() { // all20-error {{never produces a constant expression}}418    int k = 12;419 420    *((volatile int *)&k) = 13; // all20-note {{assignment to volatile-qualified type 'volatile int' is not allowed in a constant expression}}421  }422 423#if __cplusplus >= 202302L424  struct S {425    volatile int k;426  };427  constexpr int test5() {428    S s;429    s.k = 12; // all-note {{assignment to volatile-qualified type 'volatile int' is not}}430 431    return 0;432  }433  static_assert(test5() == 0); // all-error{{not an integral constant expression}} \434                               // all-note {{in call to}}435#endif436 437  constexpr bool test6(volatile int k) { // ref20-error {{never produces a constant expression}}438    k = 14; // ref20-note {{assignment to volatile-qualified type 'volatile int' is not}} \439            // all-note {{assignment to volatile-qualified type 'volatile int' is not}}440    return true;441  }442  static_assert(test6(5)); // all-error {{not an integral constant expression}} \443                           // all-note {{in call to}}444 445  constexpr bool test7(volatile int k) { // all-note {{declared here}}446    *((int *)&k) = 13; // all-note {{assignment to volatile object 'k' is not allowed in a constant expression}}447    return true;448  }449  static_assert(test7(12)); // all-error {{not an integral constant expression}} \450                            // all-note {{in call to}}451}452 453namespace AIEWithIndex0Narrows {454  template <class _Tp> struct greater {455    constexpr void operator()(_Tp, _Tp) {}456  };457  struct S {458    constexpr S() : i_() {}459    int i_;460  };461 462  constexpr void sort(S *__first) {463    for (int __start = 0; __start >= 0; --__start) {464      greater<S>{}(__first[0], __first[0]);465    }466  }467  constexpr bool test() {468    S *ia = new S[2];469 470    sort(ia + 1);471    delete[] ia;472    return true;473  }474  static_assert(test());475}476 477#if __cplusplus >= 202302L478namespace InactiveLocalsInConditionalOp {479  struct A { constexpr A(){}; ~A(); constexpr int get() { return 10; } }; // all-note 2{{declared here}}480  constexpr int get(bool b) {481    return b ? A().get() : 1; // all-note {{non-constexpr function '~A' cannot be used in a constant expression}}482  }483  static_assert(get(false) == 1, "");484  static_assert(get(true) == 10, ""); // all-error {{not an integral constant expression}} \485                                      // all-note {{in call to}}486 487  static_assert( (false ? A().get() : 1) == 1);488  static_assert( (true ? A().get() : 1) == 1); // all-error {{not an integral constant expression}} \489                                               // all-note {{non-constexpr function '~A' cannot be used in a constant expression}}490 491  constexpr bool test2(bool b) {492    unsigned long __ms = b ? (const unsigned long &)0 : __ms;493    return true;494  }495  static_assert(test2(true));496 497}498#endif499