brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.5 KiB · 92698ec Raw
367 lines · cpp
1// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++14-extensions -Werror=c++20-extensions %s2// RUN: %clang_cc1 -verify -std=c++14 -fcxx-exceptions -DCXX14 -Werror=c++20-extensions %s3// RUN: %clang_cc1 -verify -std=c++20 -fcxx-exceptions -DCXX14 -DCXX2A %s4 5namespace N {6  typedef char C;7}8 9namespace M {10  typedef double D;11}12 13struct NonLiteral { // expected-note 2{{no constexpr constructors}}14  NonLiteral() {}15  NonLiteral(int) {}16};17struct Literal {18  constexpr Literal() {}19  explicit Literal(int); // expected-note 2 {{here}}20  operator int() const { return 0; }21};22 23// In the definition of a constexpr constructor, each of the parameter types24// shall be a literal type.25struct S {26  constexpr S(int, N::C) {}27  constexpr S(int, NonLiteral, N::C) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}28  constexpr S(int, NonLiteral = 42) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}29 30  // In addition, either its function-body shall be = delete or = default31  constexpr S() = default;32  constexpr S(Literal) = delete;33};34 35// or it shall satisfy the following constraints:36 37// - the class shall not have any virtual base classes;38struct T : virtual S { // expected-note {{here}}39  constexpr T() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}40};41namespace IndirectVBase {42  struct A {};43  struct B : virtual A {}; // expected-note {{here}}44  class C : public B {45  public:46    constexpr C() {} // expected-error {{constexpr constructor not allowed in class with virtual base class}}47  };48}49 50// - its function-body shall not be a function-try-block;51struct U {52  constexpr U()53    try54#ifndef CXX2A55  // expected-error@-2 {{function try block in constexpr constructor is a C++20 extension}}56#endif57    : u() {58#ifndef CXX1459  // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}}60#endif61  } catch (...) {62    throw;63  }64  int u;65};66 67// - the compound-statememt of its function-body shall contain only68struct V {69  constexpr V() {70    //  - null statements,71    ;72 73    //  - static_assert-declarations,74    static_assert(true, "the impossible happened!");75 76    //  - typedef declarations and alias-declarations that do not define classes77    //    or enumerations,78    typedef int I;79    typedef struct S T;80    using J = int;81    using K = int[sizeof(I) + sizeof(J)];82    // Note, the standard requires we reject this.83    struct U;84 85    //  - using-declarations,86    using N::C;87 88    //  - and using-directives;89    using namespace N;90  }91 92  constexpr V(int(&)[1]) {93    for (int n = 0; n < 10; ++n)94      /**/;95#ifndef CXX1496    // expected-error@-3 {{statement not allowed in constexpr constructor}}97#endif98  }99  constexpr V(int(&)[2]) {100    constexpr int a = 0;101#ifndef CXX14102    // expected-error@-2 {{variable declaration in a constexpr constructor is a C++14 extension}}103#endif104  }105  constexpr V(int(&)[3]) {106    constexpr int ForwardDecl(int);107#ifndef CXX14108    // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}}109#endif110  }111  constexpr V(int(&)[4]) {112    typedef struct { } S1;113#ifndef CXX14114    // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}}115#endif116  }117  constexpr V(int(&)[5]) {118    using S2 = struct { };119#ifndef CXX14120    // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}}121#endif122  }123  constexpr V(int(&)[6]) {124    struct S3 { };125#ifndef CXX14126    // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}}127#endif128  }129  constexpr V(int(&)[7]) {130    return;131#ifndef CXX14132    // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}}133#endif134  }135};136 137// - every non-static data member and base class sub-object shall be initialized138struct W {139  int n;140  constexpr W() {}141#ifndef CXX2A142  // expected-error@-2 {{constexpr constructor that does not initialize all members}}143  // expected-note@-4 {{member not initialized by constructor}}144#endif145};146struct AnonMembers {147  int a; // expected-note 0-1{{member not initialized by constructor}}148  union { // expected-note 0-2{{member not initialized by constructor}}149    char b;150    struct {151      double c;152      long d; // expected-note 0-1{{member not initialized by constructor}}153    };154    union {155      char e;156      void *f;157    };158  };159  struct { // expected-note 0-1{{member not initialized by constructor}}160    long long g;161    struct {162      int h; // expected-note 0-1{{member not initialized by constructor}}163      double i; // expected-note 0-1{{member not initialized by constructor}}164    };165    union { // expected-note 0-2{{member not initialized by constructor}}166      char *j;167      AnonMembers *k;168    };169  };170 171  constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok172  // missing d, i, j/k union173  constexpr AnonMembers(int(&)[2]) : a(), c(), g(), h() {}174#ifndef CXX2A175  // expected-error@-2 {{constexpr constructor that does not initialize all members}}176#endif177  constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok178  // missing h, j/k union179  constexpr AnonMembers(int(&)[4]) : a(), c(), d(), g(), i() {}180#ifndef CXX2A181  // expected-error@-2 {{constexpr constructor that does not initialize all members}}182#endif183  // missing b/c/d/e/f union184  constexpr AnonMembers(int(&)[5]) : a(), g(), h(), i(), k() {}185#ifndef CXX2A186  // expected-error@-2 {{constexpr constructor that does not initialize all members}}187#endif188  // missing a, b/c/d/e/f union, g/h/i/j/k struct189  constexpr AnonMembers(int(&)[6]) {}190#ifndef CXX2A191  // expected-error@-2 {{constexpr constructor that does not initialize all members}}192#endif193};194 195union Empty {196  constexpr Empty() {} // ok197} constexpr empty1;198 199struct EmptyVariant {200  union {}; // expected-warning {{does not declare anything}}201  struct {}; // expected-warning {{does not declare anything}}202  constexpr EmptyVariant() {} // ok203} constexpr empty2;204 205template<typename T> using Int = int;206template<typename T>207struct TemplateInit {208  T a;209  int b; // desired-note {{not initialized}}210  Int<T> c; // desired-note {{not initialized}}211  struct {212    T d;213    int e; // desired-note {{not initialized}}214    Int<T> f; // desired-note {{not initialized}}215  };216  struct {217    Literal l;218    Literal m;219    Literal n[3];220  };221  union { // desired-note {{not initialized}}222    T g;223    T h;224  };225  // FIXME: This is ill-formed (no diagnostic required). We should diagnose it.226  constexpr TemplateInit() {} // desired-error {{must initialize all members}}227};228template<typename T> struct TemplateInit2 {229  Literal l;230  constexpr TemplateInit2() {} // ok231};232 233template<typename T> struct weak_ptr {234  constexpr weak_ptr() : p(0) {}235  T *p;236};237template<typename T> struct enable_shared_from_this {238  weak_ptr<T> weak_this;239  constexpr enable_shared_from_this() {} // ok240};241constexpr int f(enable_shared_from_this<int>);242 243// - every constructor involved in initializing non-static data members and base244//   class sub-objects shall be a constexpr constructor.245// This will no longer be the case once we support P2448R2246struct ConstexprBaseMemberCtors : Literal {247  Literal l;248 249  constexpr ConstexprBaseMemberCtors() : Literal(), l() {} // ok250  constexpr ConstexprBaseMemberCtors(char) : // expected-error {{constexpr constructor never produces a constant expression}}251    Literal(0), // expected-note {{non-constexpr constructor}}252    l() {}253  constexpr ConstexprBaseMemberCtors(double) : Literal(), // expected-error {{constexpr constructor never produces a constant expression}}254    l(0) // expected-note {{non-constexpr constructor}}255  {}256};257 258// - every assignment-expression that is an initializer-clause appearing259//   directly or indirectly within a brace-or-equal-initializer for a non-static260//   data member that is not named by a mem-initializer-id shall be a constant261//   expression; and262//263// Note, we deliberately do not implement this bullet, so that we can allow the264// following example. (See N3308).265struct X {266  int a = 0;267  int b = 2 * a + 1; // ok, not a constant expression.268 269  constexpr X() {}270  constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1271};272 273union XU1 { int a; constexpr XU1() = default; };274#ifndef CXX2A275// expected-error@-2{{cannot be marked constexpr}}276#endif277union XU2 { int a = 1; constexpr XU2() = default; };278 279struct XU3 {280  union {281    int a;282  };283  constexpr XU3() = default;284#ifndef CXX2A285  // expected-error@-2{{cannot be marked constexpr}}286#endif287};288struct XU4 {289  union {290    int a = 1;291  };292  constexpr XU4() = default;293};294 295static_assert(XU2().a == 1, "");296static_assert(XU4().a == 1, "");297 298//  - every implicit conversion used in converting a constructor argument to the299//    corresponding parameter type and converting a full-expression to the300//    corresponding member type shall be one of those allowed in a constant301//    expression.302//303// We implement the proposed resolution of DR1364 and ignore this bullet.304// However, we implement the intent of this wording as part of the p5 check that305// the function must be able to produce a constant expression.306int kGlobal; // expected-note {{here}}307struct Z {308  constexpr Z(int a) : n(a) {}309  constexpr Z() : n(kGlobal) {} // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}}310  int n;311};312 313 314namespace StdExample {315  struct Length {316    explicit constexpr Length(int i = 0) : val(i) { }317  private:318      int val;319  };320}321 322namespace CtorLookup {323  // Ensure that we look up which constructor will actually be used.324  struct A {325    constexpr A(const A&) {}326    A(A&) {}327    constexpr A(int = 0);328  };329 330  struct B : A {331    B() = default;332    constexpr B(const B&);333    constexpr B(B&);334  };335  constexpr B::B(const B&) = default;336  constexpr B::B(B&) = default; // expected-error {{cannot be marked constexpr}}337 338  struct C {339    A a;340    C() = default;341    constexpr C(const C&);342    constexpr C(C&);343  };344  constexpr C::C(const C&) = default;345  constexpr C::C(C&) = default; // expected-error {{cannot be marked constexpr}}346}347 348namespace PR14503 {349  template<typename> struct V {350    union {351      int n;352      struct {353        int x,354            y; // expected-note {{subobject declared here}}355      };356    };357    constexpr V() : x(0) {}358  };359 360  // The constructor is still 'constexpr' here, but the result is not intended361  // to be a constant expression. The standard is not clear on how this should362  // work.363  constexpr V<int> v; // expected-error {{constant expression}} expected-note {{subobject 'y' is not initialized}}364 365  constexpr int k = V<int>().x; // FIXME: ok?366}367