p4.cpp revision ce61715606b5f55ccc023720cdf9c1a796b0d526
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
4namespace N {
5  typedef char C;
6}
7
8namespace M {
9  typedef double D;
10}
11
12struct NonLiteral { // expected-note 2{{no constexpr constructors}}
13  NonLiteral() {}
14  NonLiteral(int) {}
15};
16struct 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.
24struct 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;
37struct T : virtual S { // expected-note {{here}}
38  constexpr T() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
39};
40namespace 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;
50struct 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
61struct 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
131struct W {
132  int n; // expected-note {{member not initialized by constructor}}
133  constexpr W() {} // expected-error {{constexpr constructor must initialize all members}}
134};
135struct 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
172union Empty {
173  constexpr Empty() {} // ok
174} constexpr empty1;
175
176struct EmptyVariant {
177  union {};
178  struct {};
179  constexpr EmptyVariant() {} // ok
180} constexpr empty2;
181
182template<typename T> using Int = int;
183template<typename T>
184struct 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};
205template<typename T> struct TemplateInit2 {
206  Literal l;
207  constexpr TemplateInit2() {} // ok
208};
209
210template<typename T> struct weak_ptr {
211  constexpr weak_ptr() : p(0) {}
212  T *p;
213};
214template<typename T> struct enable_shared_from_this {
215  weak_ptr<T> weak_this;
216  constexpr enable_shared_from_this() {} // ok
217};
218constexpr 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.
222struct 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).
241struct 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
249union XU1 { int a; constexpr XU1() = default; }; // expected-error{{not constexpr}}
250union XU2 { int a = 1; constexpr XU2() = default; };
251
252struct XU3 {
253  union {
254    int a;
255  };
256  constexpr XU3() = default; // expected-error{{not constexpr}}
257};
258struct XU4 {
259  union {
260    int a = 1;
261  };
262  constexpr XU4() = default;
263};
264
265static_assert(XU2().a == 1, "");
266static_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.
276int kGlobal; // expected-note {{here}}
277struct 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
284namespace StdExample {
285  struct Length {
286    explicit constexpr Length(int i = 0) : val(i) { }
287  private:
288      int val;
289  };
290}
291
292namespace 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