Home | History | Annotate | Download | only in dcl.constexpr
      1 // RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions %s
      2 
      3 namespace N {
      4   typedef char C;
      5 }
      6 
      7 namespace M {
      8   typedef double D;
      9 }
     10 
     11 struct NonLiteral { // expected-note 2{{no constexpr constructors}}
     12   NonLiteral() {}
     13   NonLiteral(int) {}
     14 };
     15 struct Literal {
     16   constexpr Literal() {}
     17   explicit Literal(int); // expected-note 2 {{here}}
     18   operator int() const { return 0; }
     19 };
     20 
     21 // In the definition of a constexpr constructor, each of the parameter types
     22 // shall be a literal type.
     23 struct S {
     24   constexpr S(int, N::C) {}
     25   constexpr S(int, NonLiteral, N::C) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
     26   constexpr S(int, NonLiteral = 42) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
     27 
     28   // In addition, either its function-body shall be = delete or = default
     29   constexpr S() = default;
     30   constexpr S(Literal) = delete;
     31 };
     32 
     33 // or it shall satisfy the following constraints:
     34 
     35 // - the class shall not have any virtual base classes;
     36 struct T : virtual S { // expected-note {{here}}
     37   constexpr T() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
     38 };
     39 namespace IndirectVBase {
     40   struct A {};
     41   struct B : virtual A {}; // expected-note {{here}}
     42   class C : public B {
     43   public:
     44     constexpr C() {} // expected-error {{constexpr constructor not allowed in class with virtual base class}}
     45   };
     46 }
     47 
     48 // - its function-body shall not be a function-try-block;
     49 struct U {
     50   constexpr U()
     51     try // expected-error {{function try block not allowed in constexpr constructor}}
     52     : u() {
     53   } catch (...) {
     54     throw;
     55   }
     56   int u;
     57 };
     58 
     59 // - the compound-statememt of its function-body shall contain only
     60 struct V {
     61   constexpr V() {
     62     //  - null statements,
     63     ;
     64 
     65     //  - static_assert-declarations,
     66     static_assert(true, "the impossible happened!");
     67 
     68     //  - typedef declarations and alias-declarations that do not define classes
     69     //    or enumerations,
     70     typedef int I;
     71     typedef struct S T;
     72     using J = int;
     73     using K = int[sizeof(I) + sizeof(J)];
     74     // Note, the standard requires we reject this.
     75     struct U;
     76 
     77     //  - using-declarations,
     78     using N::C;
     79 
     80     //  - and using-directives;
     81     using namespace N;
     82   }
     83 
     84   constexpr V(int(&)[1]) {
     85     for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr constructor}}
     86       /**/;
     87   }
     88   constexpr V(int(&)[2]) {
     89     constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr constructor}}
     90   }
     91   constexpr V(int(&)[3]) {
     92     constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr constructor}}
     93   }
     94   constexpr V(int(&)[4]) {
     95     typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr constructor}}
     96   }
     97   constexpr V(int(&)[5]) {
     98     using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr constructor}}
     99   }
    100   constexpr V(int(&)[6]) {
    101     struct S3 { }; // expected-error {{types cannot be defined in a constexpr constructor}}
    102   }
    103   constexpr V(int(&)[7]) {
    104     return; // expected-error {{statement not allowed in constexpr constructor}}
    105   }
    106 };
    107 
    108 // - every non-static data member and base class sub-object shall be initialized
    109 struct W {
    110   int n; // expected-note {{member not initialized by constructor}}
    111   constexpr W() {} // expected-error {{constexpr constructor must initialize all members}}
    112 };
    113 struct AnonMembers {
    114   int a; // expected-note {{member not initialized by constructor}}
    115   union { // expected-note 2{{member not initialized by constructor}}
    116     char b;
    117     struct {
    118       double c;
    119       long d; // expected-note {{member not initialized by constructor}}
    120     };
    121     union {
    122       char e;
    123       void *f;
    124     };
    125   };
    126   struct { // expected-note {{member not initialized by constructor}}
    127     long long g;
    128     struct {
    129       int h; // expected-note {{member not initialized by constructor}}
    130       double i; // expected-note {{member not initialized by constructor}}
    131     };
    132     union { // expected-note 2{{member not initialized by constructor}}
    133       char *j;
    134       AnonMembers *k;
    135     };
    136   };
    137 
    138   constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok
    139   // missing d, i, j/k union
    140   constexpr AnonMembers(int(&)[2]) : a(), c(), g(), h() {} // expected-error {{constexpr constructor must initialize all members}}
    141   constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok
    142   // missing h, j/k union
    143   constexpr AnonMembers(int(&)[4]) : a(), c(), d(), g(), i() {} // expected-error {{constexpr constructor must initialize all members}}
    144   // missing b/c/d/e/f union
    145   constexpr AnonMembers(int(&)[5]) : a(), g(), h(), i(), k() {} // expected-error {{constexpr constructor must initialize all members}}
    146   // missing a, b/c/d/e/f union, g/h/i/j/k struct
    147   constexpr AnonMembers(int(&)[6]) {} // expected-error {{constexpr constructor must initialize all members}}
    148 };
    149 
    150 union Empty {
    151   constexpr Empty() {} // ok
    152 } constexpr empty1;
    153 
    154 struct EmptyVariant {
    155   union {};
    156   struct {};
    157   constexpr EmptyVariant() {} // ok
    158 } constexpr empty2;
    159 
    160 template<typename T> using Int = int;
    161 template<typename T>
    162 struct TemplateInit {
    163   T a;
    164   int b; // desired-note {{not initialized}}
    165   Int<T> c; // desired-note {{not initialized}}
    166   struct {
    167     T d;
    168     int e; // desired-note {{not initialized}}
    169     Int<T> f; // desired-note {{not initialized}}
    170   };
    171   struct {
    172     Literal l;
    173     Literal m;
    174     Literal n[3];
    175   };
    176   union { // desired-note {{not initialized}}
    177     T g;
    178     T h;
    179   };
    180   // FIXME: This is ill-formed (no diagnostic required). We should diagnose it.
    181   constexpr TemplateInit() {} // desired-error {{must initialize all members}}
    182 };
    183 template<typename T> struct TemplateInit2 {
    184   Literal l;
    185   constexpr TemplateInit2() {} // ok
    186 };
    187 
    188 template<typename T> struct weak_ptr {
    189   constexpr weak_ptr() : p(0) {}
    190   T *p;
    191 };
    192 template<typename T> struct enable_shared_from_this {
    193   weak_ptr<T> weak_this;
    194   constexpr enable_shared_from_this() {} // ok
    195 };
    196 constexpr int f(enable_shared_from_this<int>);
    197 
    198 // - every constructor involved in initializing non-static data members and base
    199 //   class sub-objects shall be a constexpr constructor.
    200 struct ConstexprBaseMemberCtors : Literal {
    201   Literal l;
    202 
    203   constexpr ConstexprBaseMemberCtors() : Literal(), l() {} // ok
    204   constexpr ConstexprBaseMemberCtors(char) : // expected-error {{constexpr constructor never produces a constant expression}}
    205     Literal(0), // expected-note {{non-constexpr constructor}}
    206     l() {}
    207   constexpr ConstexprBaseMemberCtors(double) : Literal(), // expected-error {{constexpr constructor never produces a constant expression}}
    208     l(0) // expected-note {{non-constexpr constructor}}
    209   {}
    210 };
    211 
    212 // - every assignment-expression that is an initializer-clause appearing
    213 //   directly or indirectly within a brace-or-equal-initializer for a non-static
    214 //   data member that is not named by a mem-initializer-id shall be a constant
    215 //   expression; and
    216 //
    217 // Note, we deliberately do not implement this bullet, so that we can allow the
    218 // following example. (See N3308).
    219 struct X {
    220   int a = 0;
    221   int b = 2 * a + 1; // ok, not a constant expression.
    222 
    223   constexpr X() {}
    224   constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1
    225 };
    226 
    227 union XU1 { int a; constexpr XU1() = default; }; // expected-error{{not constexpr}}
    228 union XU2 { int a = 1; constexpr XU2() = default; };
    229 
    230 struct XU3 {
    231   union {
    232     int a;
    233   };
    234   constexpr XU3() = default; // expected-error{{not constexpr}}
    235 };
    236 struct XU4 {
    237   union {
    238     int a = 1;
    239   };
    240   constexpr XU4() = default;
    241 };
    242 
    243 static_assert(XU2().a == 1, "");
    244 static_assert(XU4().a == 1, "");
    245 
    246 //  - every implicit conversion used in converting a constructor argument to the
    247 //    corresponding parameter type and converting a full-expression to the
    248 //    corresponding member type shall be one of those allowed in a constant
    249 //    expression.
    250 //
    251 // We implement the proposed resolution of DR1364 and ignore this bullet.
    252 // However, we implement the intent of this wording as part of the p5 check that
    253 // the function must be able to produce a constant expression.
    254 int kGlobal; // expected-note {{here}}
    255 struct Z {
    256   constexpr Z(int a) : n(a) {}
    257   constexpr Z() : n(kGlobal) {} // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}}
    258   int n;
    259 };
    260 
    261 
    262 namespace StdExample {
    263   struct Length {
    264     explicit constexpr Length(int i = 0) : val(i) { }
    265   private:
    266       int val;
    267   };
    268 }
    269 
    270 namespace CtorLookup {
    271   // Ensure that we look up which constructor will actually be used.
    272   struct A {
    273     constexpr A(const A&) {}
    274     A(A&) {}
    275     constexpr A(int = 0);
    276   };
    277 
    278   struct B : A {
    279     B() = default;
    280     constexpr B(const B&);
    281     constexpr B(B&);
    282   };
    283   constexpr B::B(const B&) = default;
    284   constexpr B::B(B&) = default; // expected-error {{not constexpr}}
    285 
    286   struct C {
    287     A a;
    288     C() = default;
    289     constexpr C(const C&);
    290     constexpr C(C&);
    291   };
    292   constexpr C::C(const C&) = default;
    293   constexpr C::C(C&) = default; // expected-error {{not constexpr}}
    294 }
    295