• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++14-extensions -Werror=c++20-extensions %s
2 // RUN: %clang_cc1 -verify -std=c++14 -fcxx-exceptions -DCXX14 -Werror=c++20-extensions %s
3 // RUN: %clang_cc1 -verify -std=c++20 -fcxx-exceptions -DCXX14 -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}}
NonLiteralNonLiteral14   NonLiteral() {}
NonLiteralNonLiteral15   NonLiteral(int) {}
16 };
17 struct Literal {
LiteralLiteral18   constexpr Literal() {}
19   explicit Literal(int); // expected-note 2 {{here}}
operator intLiteral20   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 {
SS26   constexpr S(int, N::C) {}
SS27   constexpr S(int, NonLiteral, N::C) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}}
SS28   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}}
TT39   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:
C()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 {
UU52   constexpr U()
53     try
54 #ifndef CXX2A
55   // expected-error@-2 {{function try block in constexpr constructor is a C++20 extension}}
56 #endif
57     : u() {
58 #ifndef CXX14
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 {
VV69   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 
VV92   constexpr V(int(&)[1]) {
93     for (int n = 0; n < 10; ++n)
94       /**/;
95 #ifndef CXX14
96     // expected-error@-3 {{statement not allowed in constexpr constructor}}
97 #endif
98   }
VV99   constexpr V(int(&)[2]) {
100     constexpr int a = 0;
101 #ifndef CXX14
102     // expected-error@-2 {{variable declaration in a constexpr constructor is a C++14 extension}}
103 #endif
104   }
VV105   constexpr V(int(&)[3]) {
106     constexpr int ForwardDecl(int);
107 #ifndef CXX14
108     // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}}
109 #endif
110   }
VV111   constexpr V(int(&)[4]) {
112     typedef struct { } S1;
113 #ifndef CXX14
114     // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}}
115 #endif
116   }
VV117   constexpr V(int(&)[5]) {
118     using S2 = struct { };
119 #ifndef CXX14
120     // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}}
121 #endif
122   }
VV123   constexpr V(int(&)[6]) {
124     struct S3 { };
125 #ifndef CXX14
126     // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}}
127 #endif
128   }
VV129   constexpr V(int(&)[7]) {
130     return;
131 #ifndef CXX14
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;
WW140   constexpr W() {}
141 #ifndef CXX2A
142   // expected-error@-2 {{constexpr constructor that does not initialize all members}}
143   // expected-note@-4 {{member not initialized by constructor}}
144 #endif
145 };
146 struct AnonMembers {
147   int a; // expected-note 0-1{{member not initialized by constructor}}
148   union { // expected-note 0-2{{member not initialized by constructor}}
149     char b;
150     struct {
151       double c;
152       long d; // expected-note 0-1{{member not initialized by constructor}}
153     };
154     union {
155       char e;
156       void *f;
157     };
158   };
159   struct { // expected-note 0-1{{member not initialized by constructor}}
160     long long g;
161     struct {
162       int h; // expected-note 0-1{{member not initialized by constructor}}
163       double i; // expected-note 0-1{{member not initialized by constructor}}
164     };
165     union { // expected-note 0-2{{member not initialized by constructor}}
166       char *j;
167       AnonMembers *k;
168     };
169   };
170 
AnonMembersAnonMembers171   constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok
172   // missing d, i, j/k union
AnonMembersAnonMembers173   constexpr AnonMembers(int(&)[2]) : a(), c(), g(), h() {}
174 #ifndef CXX2A
175   // expected-error@-2 {{constexpr constructor that does not initialize all members}}
176 #endif
AnonMembersAnonMembers177   constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok
178   // missing h, j/k union
AnonMembersAnonMembers179   constexpr AnonMembers(int(&)[4]) : a(), c(), d(), g(), i() {}
180 #ifndef CXX2A
181   // expected-error@-2 {{constexpr constructor that does not initialize all members}}
182 #endif
183   // missing b/c/d/e/f union
AnonMembersAnonMembers184   constexpr AnonMembers(int(&)[5]) : a(), g(), h(), i(), k() {}
185 #ifndef CXX2A
186   // expected-error@-2 {{constexpr constructor that does not initialize all members}}
187 #endif
188   // missing a, b/c/d/e/f union, g/h/i/j/k struct
AnonMembersAnonMembers189   constexpr AnonMembers(int(&)[6]) {}
190 #ifndef CXX2A
191   // expected-error@-2 {{constexpr constructor that does not initialize all members}}
192 #endif
193 };
194 
195 union Empty {
Empty()196   constexpr Empty() {} // ok
197 } constexpr empty1;
198 
199 struct EmptyVariant {
200   union {}; // expected-warning {{does not declare anything}}
201   struct {}; // expected-warning {{does not declare anything}}
EmptyVariantEmptyVariant202   constexpr EmptyVariant() {} // ok
203 } constexpr empty2;
204 
205 template<typename T> using Int = int;
206 template<typename T>
207 struct TemplateInit {
208   T a;
209   int b; // desired-note {{not initialized}}
210   Int<T> c; // desired-note {{not initialized}}
211   struct {
212     T d;
213     int e; // desired-note {{not initialized}}
214     Int<T> f; // desired-note {{not initialized}}
215   };
216   struct {
217     Literal l;
218     Literal m;
219     Literal n[3];
220   };
221   union { // desired-note {{not initialized}}
222     T g;
223     T h;
224   };
225   // FIXME: This is ill-formed (no diagnostic required). We should diagnose it.
TemplateInitTemplateInit226   constexpr TemplateInit() {} // desired-error {{must initialize all members}}
227 };
228 template<typename T> struct TemplateInit2 {
229   Literal l;
TemplateInit2TemplateInit2230   constexpr TemplateInit2() {} // ok
231 };
232 
233 template<typename T> struct weak_ptr {
weak_ptrweak_ptr234   constexpr weak_ptr() : p(0) {}
235   T *p;
236 };
237 template<typename T> struct enable_shared_from_this {
238   weak_ptr<T> weak_this;
enable_shared_from_thisenable_shared_from_this239   constexpr enable_shared_from_this() {} // ok
240 };
241 constexpr int f(enable_shared_from_this<int>);
242 
243 // - every constructor involved in initializing non-static data members and base
244 //   class sub-objects shall be a constexpr constructor.
245 struct ConstexprBaseMemberCtors : Literal {
246   Literal l;
247 
ConstexprBaseMemberCtorsConstexprBaseMemberCtors248   constexpr ConstexprBaseMemberCtors() : Literal(), l() {} // ok
ConstexprBaseMemberCtorsConstexprBaseMemberCtors249   constexpr ConstexprBaseMemberCtors(char) : // expected-error {{constexpr constructor never produces a constant expression}}
250     Literal(0), // expected-note {{non-constexpr constructor}}
251     l() {}
ConstexprBaseMemberCtorsConstexprBaseMemberCtors252   constexpr ConstexprBaseMemberCtors(double) : Literal(), // expected-error {{constexpr constructor never produces a constant expression}}
253     l(0) // expected-note {{non-constexpr constructor}}
254   {}
255 };
256 
257 // - every assignment-expression that is an initializer-clause appearing
258 //   directly or indirectly within a brace-or-equal-initializer for a non-static
259 //   data member that is not named by a mem-initializer-id shall be a constant
260 //   expression; and
261 //
262 // Note, we deliberately do not implement this bullet, so that we can allow the
263 // following example. (See N3308).
264 struct X {
265   int a = 0;
266   int b = 2 * a + 1; // ok, not a constant expression.
267 
XX268   constexpr X() {}
XX269   constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1
270 };
271 
272 union XU1 { int a; constexpr XU1() = default; };
273 #ifndef CXX2A
274 // expected-error@-2{{not constexpr}}
275 #endif
276 union XU2 { int a = 1; constexpr XU2() = default; };
277 
278 struct XU3 {
279   union {
280     int a;
281   };
282   constexpr XU3() = default;
283 #ifndef CXX2A
284   // expected-error@-2{{not constexpr}}
285 #endif
286 };
287 struct XU4 {
288   union {
289     int a = 1;
290   };
291   constexpr XU4() = default;
292 };
293 
294 static_assert(XU2().a == 1, "");
295 static_assert(XU4().a == 1, "");
296 
297 //  - every implicit conversion used in converting a constructor argument to the
298 //    corresponding parameter type and converting a full-expression to the
299 //    corresponding member type shall be one of those allowed in a constant
300 //    expression.
301 //
302 // We implement the proposed resolution of DR1364 and ignore this bullet.
303 // However, we implement the intent of this wording as part of the p5 check that
304 // the function must be able to produce a constant expression.
305 int kGlobal; // expected-note {{here}}
306 struct Z {
ZZ307   constexpr Z(int a) : n(a) {}
ZZ308   constexpr Z() : n(kGlobal) {} // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}}
309   int n;
310 };
311 
312 
313 namespace StdExample {
314   struct Length {
LengthStdExample::Length315     explicit constexpr Length(int i = 0) : val(i) { }
316   private:
317       int val;
318   };
319 }
320 
321 namespace CtorLookup {
322   // Ensure that we look up which constructor will actually be used.
323   struct A {
ACtorLookup::A324     constexpr A(const A&) {}
ACtorLookup::A325     A(A&) {}
326     constexpr A(int = 0);
327   };
328 
329   struct B : A {
330     B() = default;
331     constexpr B(const B&);
332     constexpr B(B&);
333   };
334   constexpr B::B(const B&) = default;
335   constexpr B::B(B&) = default; // expected-error {{not constexpr}}
336 
337   struct C {
338     A a;
339     C() = default;
340     constexpr C(const C&);
341     constexpr C(C&);
342   };
343   constexpr C::C(const C&) = default;
344   constexpr C::C(C&) = default; // expected-error {{not constexpr}}
345 }
346 
347 namespace PR14503 {
348   template<typename> struct V {
349     union {
350       int n;
351       struct {
352         int x,
353             y; // expected-note {{subobject declared here}}
354       };
355     };
VPR14503::V356     constexpr V() : x(0) {}
357   };
358 
359   // The constructor is still 'constexpr' here, but the result is not intended
360   // to be a constant expression. The standard is not clear on how this should
361   // work.
362   constexpr V<int> v; // expected-error {{constant expression}} expected-note {{subobject of type 'int' is not initialized}}
363 
364   constexpr int k = V<int>().x; // FIXME: ok?
365 }
366