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