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