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   operator int() const { return 0; }
     18 };
     19 
     20 // Note, the wording applies constraints to the definition of constexpr
     21 // constructors, but we intentionally apply all that we can to the declaration
     22 // instead. See DR1360.
     23 
     24 // In the definition of a constexpr constructor, each of the parameter types
     25 // shall be a literal type.
     26 struct S {
     27   constexpr S(int, N::C);
     28   constexpr S(int, NonLiteral, N::C); // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
     29   constexpr S(int, NonLiteral = 42); // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
     30 
     31   // In addition, either its function-body shall be = delete or = default
     32   constexpr S() = default;
     33   constexpr S(Literal) = delete;
     34 };
     35 
     36 // or it shall satisfy the following constraints:
     37 
     38 // - the class shall not have any virtual base classes;
     39 struct T : virtual S { // expected-note {{here}}
     40   constexpr T(); // expected-error {{constexpr constructor not allowed in struct with virtual base classes}}
     41 };
     42 namespace IndirectVBase {
     43   struct A {};
     44   struct B : virtual A {}; // expected-note {{here}}
     45   class C : public B {
     46   public:
     47     constexpr C(); // expected-error {{constexpr constructor not allowed in class with virtual base classes}}
     48   };
     49 }
     50 
     51 // - its function-body shall not be a function-try-block;
     52 struct U {
     53   constexpr U()
     54     try // expected-error {{function try block not allowed in constexpr constructor}}
     55     : u() {
     56   } catch (...) {
     57     throw;
     58   }
     59   int u;
     60 };
     61 
     62 // - the compound-statememt of its function-body shall contain only
     63 struct V {
     64   constexpr V() {
     65     //  - null statements,
     66     ;
     67 
     68     //  - static_assert-declarations,
     69     static_assert(true, "the impossible happened!");
     70 
     71     //  - typedef declarations and alias-declarations that do not define classes
     72     //    or enumerations,
     73     typedef int I;
     74     typedef struct S T;
     75     using J = int;
     76     using K = int[sizeof(I) + sizeof(J)];
     77     // Note, the standard requires we reject this.
     78     struct U;
     79 
     80     //  - using-declarations,
     81     using N::C;
     82 
     83     //  - and using-directives;
     84     using namespace N;
     85   }
     86 
     87   constexpr V(int(&)[1]) {
     88     for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr constructor}}
     89       /**/;
     90   }
     91   constexpr V(int(&)[2]) {
     92     constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr constructor}}
     93   }
     94   constexpr V(int(&)[3]) {
     95     constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr constructor}}
     96   }
     97   constexpr V(int(&)[4]) {
     98     typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr constructor}}
     99   }
    100   constexpr V(int(&)[5]) {
    101     using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr constructor}}
    102   }
    103   constexpr V(int(&)[6]) {
    104     struct S3 { }; // expected-error {{types cannot be defined in a constexpr constructor}}
    105   }
    106   constexpr V(int(&)[7]) {
    107     return; // expected-error {{statement not allowed in constexpr constructor}}
    108   }
    109 };
    110 
    111 // - every non-static data member and base class sub-object shall be initialized
    112 struct W {
    113   int n; // expected-note {{member not initialized by constructor}}
    114   constexpr W() {} // expected-error {{constexpr constructor must initialize all members}}
    115 };
    116 struct AnonMembers {
    117   int a; // expected-note {{member not initialized by constructor}}
    118   union { // expected-note 2{{member not initialized by constructor}}
    119     char b;
    120     struct {
    121       double c;
    122       long d; // expected-note {{member not initialized by constructor}}
    123     };
    124     union {
    125       char e;
    126       void *f;
    127     };
    128   };
    129   struct { // expected-note {{member not initialized by constructor}}
    130     long long g;
    131     struct {
    132       int h; // expected-note {{member not initialized by constructor}}
    133       double i; // expected-note {{member not initialized by constructor}}
    134     };
    135     union { // expected-note 2{{member not initialized by constructor}}
    136       char *j;
    137       AnonMembers *k;
    138     };
    139   };
    140 
    141   constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok
    142   // missing d, i, j/k union
    143   constexpr AnonMembers(int(&)[2]) : a(), c(), g(), h() {} // expected-error {{constexpr constructor must initialize all members}}
    144   constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok
    145   // missing h, j/k union
    146   constexpr AnonMembers(int(&)[4]) : a(), c(), d(), g(), i() {} // expected-error {{constexpr constructor must initialize all members}}
    147   // missing b/c/d/e/f union
    148   constexpr AnonMembers(int(&)[5]) : a(), g(), h(), i(), k() {} // expected-error {{constexpr constructor must initialize all members}}
    149   // missing a, b/c/d/e/f union, g/h/i/j/k struct
    150   constexpr AnonMembers(int(&)[6]) {} // expected-error {{constexpr constructor must initialize all members}}
    151 };
    152 
    153 template<typename T> using Int = int;
    154 template<typename T>
    155 struct TemplateInit {
    156   T a;
    157   int b; // desired-note {{not initialized}}
    158   Int<T> c; // desired-note {{not initialized}}
    159   struct {
    160     T d;
    161     int e; // desired-note {{not initialized}}
    162     Int<T> f; // desired-note {{not initialized}}
    163   };
    164   struct {
    165     Literal l;
    166     Literal m;
    167     Literal n[3];
    168   };
    169   union { // desired-note {{not initialized}}
    170     T g;
    171     T h;
    172   };
    173   // FIXME: This is ill-formed (no diagnostic required). We should diagnose it.
    174   constexpr TemplateInit() {} // desired-error {{must initialize all members}}
    175 };
    176 template<typename T> struct TemplateInit2 {
    177   Literal l;
    178   constexpr TemplateInit2() {} // ok
    179 };
    180 
    181 template<typename T> struct weak_ptr {
    182   constexpr weak_ptr() : p(0) {}
    183   T *p;
    184 };
    185 template<typename T> struct enable_shared_from_this {
    186   weak_ptr<T> weak_this;
    187   constexpr enable_shared_from_this() {} // ok
    188 };
    189 constexpr int f(enable_shared_from_this<int>);
    190 
    191 // - every constructor involved in initializing non-static data members and base
    192 //   class sub-objects shall be a constexpr constructor.
    193 //
    194 // FIXME: Implement this as part of the 'must be able to produce a constant
    195 // expression' rules.
    196 
    197 // - every assignment-expression that is an initializer-caluse appearing
    198 //   directly or indirectly within a brace-or-equal-initializer for a non-static
    199 //   data member that is not named by a mem-initializer-id shall be a constant
    200 //   expression; and
    201 //
    202 // Note, we deliberately do not implement this bullet, so that we can allow the
    203 // following example. (See N3308).
    204 struct X {
    205   int a = 0;
    206   int b = 2 * a + 1; // ok, not a constant expression.
    207 
    208   constexpr X() {}
    209   constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1
    210 };
    211 
    212 //  - every implicit conversion used in converting a constructor argument to the
    213 //    corresponding parameter type and converting a full-expression to the
    214 //    corresponding member type shall be one of those allowed in a constant
    215 //    expression.
    216 //
    217 // We implement the proposed resolution of DR1364 and ignore this bullet.
    218 
    219 
    220 namespace StdExample {
    221   struct Length {
    222     explicit constexpr Length(int i = 0) : val(i) { }
    223   private:
    224       int val;
    225   };
    226 }
    227