p4.cpp revision 7756afa6273cf708b5e3fbd6a6478eb2cada27e2
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// In the definition of a constexpr constructor, each of the parameter types
22// shall be a literal type.
23struct 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;
36struct T : virtual S { // expected-note {{here}}
37  constexpr T() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
38};
39namespace 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;
49struct 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
60struct 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
109struct W {
110  int n; // expected-note {{member not initialized by constructor}}
111  constexpr W() {} // expected-error {{constexpr constructor must initialize all members}}
112};
113struct 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
150union Empty {
151  constexpr Empty() {} // ok
152} constexpr empty1;
153
154struct EmptyVariant {
155  union {};
156  struct {};
157  constexpr EmptyVariant() {} // ok
158} constexpr empty2;
159
160template<typename T> using Int = int;
161template<typename T>
162struct 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};
183template<typename T> struct TemplateInit2 {
184  Literal l;
185  constexpr TemplateInit2() {} // ok
186};
187
188template<typename T> struct weak_ptr {
189  constexpr weak_ptr() : p(0) {}
190  T *p;
191};
192template<typename T> struct enable_shared_from_this {
193  weak_ptr<T> weak_this;
194  constexpr enable_shared_from_this() {} // ok
195};
196constexpr 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.
200struct 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).
219struct 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
227union XU1 { int a; constexpr XU1() = default; }; // expected-error{{not constexpr}}
228union XU2 { int a = 1; constexpr XU2() = default; };
229
230struct XU3 {
231  union {
232    int a;
233  };
234  constexpr XU3() = default; // expected-error{{not constexpr}}
235};
236struct XU4 {
237  union {
238    int a = 1;
239  };
240  constexpr XU4() = default;
241};
242
243static_assert(XU2().a == 1, "");
244static_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.
254int kGlobal; // expected-note {{here}}
255struct 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
262namespace StdExample {
263  struct Length {
264    explicit constexpr Length(int i = 0) : val(i) { }
265  private:
266      int val;
267  };
268}
269
270namespace 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); // expected-note {{previous}}
276  };
277  constexpr A::A(int = 0) {} // expected-warning {{default constructor}}
278
279  struct B : A {
280    B() = default;
281    constexpr B(const B&);
282    constexpr B(B&);
283  };
284  constexpr B::B(const B&) = default;
285  constexpr B::B(B&) = default; // expected-error {{not constexpr}}
286
287  struct C {
288    A a;
289    C() = default;
290    constexpr C(const C&);
291    constexpr C(C&);
292  };
293  constexpr C::C(const C&) = default;
294  constexpr C::C(C&) = default; // expected-error {{not constexpr}}
295}
296