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