p4.cpp revision 2fe9b7fb07dff15dd15dd8755a9a9e6de0fe46fc
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  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.
26struct 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;
39struct T : virtual S { // expected-note {{here}}
40  constexpr T(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
41};
42namespace 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 class}}
48  };
49}
50
51// - its function-body shall not be a function-try-block;
52struct 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
63struct 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
112struct W {
113  int n; // expected-note {{member not initialized by constructor}}
114  constexpr W() {} // expected-error {{constexpr constructor must initialize all members}}
115};
116struct 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
153template<typename T> using Int = int;
154template<typename T>
155struct 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};
176template<typename T> struct TemplateInit2 {
177  Literal l;
178  constexpr TemplateInit2() {} // ok
179};
180
181template<typename T> struct weak_ptr {
182  constexpr weak_ptr() : p(0) {}
183  T *p;
184};
185template<typename T> struct enable_shared_from_this {
186  weak_ptr<T> weak_this;
187  constexpr enable_shared_from_this() {} // ok
188};
189constexpr 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).
204struct 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
220namespace StdExample {
221  struct Length {
222    explicit constexpr Length(int i = 0) : val(i) { }
223  private:
224      int val;
225  };
226}
227