[libc][NFC] Remove extra ; in exhaustive_test.h. (#124216)
[llvm-project.git] / clang / test / CXX / dcl.dcl / dcl.spec / dcl.constexpr / p4.cpp
blob92698ec1c7387d63f33c163b973477acbd40d589
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
5 namespace N {
6 typedef char C;
9 namespace M {
10 typedef double D;
13 struct NonLiteral { // expected-note 2{{no constexpr constructors}}
14 NonLiteral() {}
15 NonLiteral(int) {}
17 struct Literal {
18 constexpr Literal() {}
19 explicit Literal(int); // expected-note 2 {{here}}
20 operator int() const { return 0; }
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}}
30 // In addition, either its function-body shall be = delete or = default
31 constexpr S() = default;
32 constexpr S(Literal) = delete;
35 // or it shall satisfy the following constraints:
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}}
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}}
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++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;
64 int u;
67 // - the compound-statememt of its function-body shall contain only
68 struct V {
69 constexpr V() {
70 // - null statements,
73 // - static_assert-declarations,
74 static_assert(true, "the impossible happened!");
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;
85 // - using-declarations,
86 using N::C;
88 // - and using-directives;
89 using namespace N;
92 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
99 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
105 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
111 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
117 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
123 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
129 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
137 // - every non-static data member and base class sub-object shall be initialized
138 struct W {
139 int n;
140 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
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}}
154 union {
155 char e;
156 void *f;
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}}
165 union { // expected-note 0-2{{member not initialized by constructor}}
166 char *j;
167 AnonMembers *k;
171 constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok
172 // missing d, i, j/k union
173 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
177 constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok
178 // missing h, j/k union
179 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
184 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
189 constexpr AnonMembers(int(&)[6]) {}
190 #ifndef CXX2A
191 // expected-error@-2 {{constexpr constructor that does not initialize all members}}
192 #endif
195 union Empty {
196 constexpr Empty() {} // ok
197 } constexpr empty1;
199 struct EmptyVariant {
200 union {}; // expected-warning {{does not declare anything}}
201 struct {}; // expected-warning {{does not declare anything}}
202 constexpr EmptyVariant() {} // ok
203 } constexpr empty2;
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}}
216 struct {
217 Literal l;
218 Literal m;
219 Literal n[3];
221 union { // desired-note {{not initialized}}
222 T g;
223 T h;
225 // FIXME: This is ill-formed (no diagnostic required). We should diagnose it.
226 constexpr TemplateInit() {} // desired-error {{must initialize all members}}
228 template<typename T> struct TemplateInit2 {
229 Literal l;
230 constexpr TemplateInit2() {} // ok
233 template<typename T> struct weak_ptr {
234 constexpr weak_ptr() : p(0) {}
235 T *p;
237 template<typename T> struct enable_shared_from_this {
238 weak_ptr<T> weak_this;
239 constexpr enable_shared_from_this() {} // ok
241 constexpr int f(enable_shared_from_this<int>);
243 // - every constructor involved in initializing non-static data members and base
244 // class sub-objects shall be a constexpr constructor.
245 // This will no longer be the case once we support P2448R2
246 struct ConstexprBaseMemberCtors : Literal {
247 Literal l;
249 constexpr ConstexprBaseMemberCtors() : Literal(), l() {} // ok
250 constexpr ConstexprBaseMemberCtors(char) : // expected-error {{constexpr constructor never produces a constant expression}}
251 Literal(0), // expected-note {{non-constexpr constructor}}
252 l() {}
253 constexpr ConstexprBaseMemberCtors(double) : Literal(), // expected-error {{constexpr constructor never produces a constant expression}}
254 l(0) // expected-note {{non-constexpr constructor}}
258 // - every assignment-expression that is an initializer-clause appearing
259 // directly or indirectly within a brace-or-equal-initializer for a non-static
260 // data member that is not named by a mem-initializer-id shall be a constant
261 // expression; and
263 // Note, we deliberately do not implement this bullet, so that we can allow the
264 // following example. (See N3308).
265 struct X {
266 int a = 0;
267 int b = 2 * a + 1; // ok, not a constant expression.
269 constexpr X() {}
270 constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1
273 union XU1 { int a; constexpr XU1() = default; };
274 #ifndef CXX2A
275 // expected-error@-2{{cannot be marked constexpr}}
276 #endif
277 union XU2 { int a = 1; constexpr XU2() = default; };
279 struct XU3 {
280 union {
281 int a;
283 constexpr XU3() = default;
284 #ifndef CXX2A
285 // expected-error@-2{{cannot be marked constexpr}}
286 #endif
288 struct XU4 {
289 union {
290 int a = 1;
292 constexpr XU4() = default;
295 static_assert(XU2().a == 1, "");
296 static_assert(XU4().a == 1, "");
298 // - every implicit conversion used in converting a constructor argument to the
299 // corresponding parameter type and converting a full-expression to the
300 // corresponding member type shall be one of those allowed in a constant
301 // expression.
303 // We implement the proposed resolution of DR1364 and ignore this bullet.
304 // However, we implement the intent of this wording as part of the p5 check that
305 // the function must be able to produce a constant expression.
306 int kGlobal; // expected-note {{here}}
307 struct Z {
308 constexpr Z(int a) : n(a) {}
309 constexpr Z() : n(kGlobal) {} // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}}
310 int n;
314 namespace StdExample {
315 struct Length {
316 explicit constexpr Length(int i = 0) : val(i) { }
317 private:
318 int val;
322 namespace CtorLookup {
323 // Ensure that we look up which constructor will actually be used.
324 struct A {
325 constexpr A(const A&) {}
326 A(A&) {}
327 constexpr A(int = 0);
330 struct B : A {
331 B() = default;
332 constexpr B(const B&);
333 constexpr B(B&);
335 constexpr B::B(const B&) = default;
336 constexpr B::B(B&) = default; // expected-error {{cannot be marked constexpr}}
338 struct C {
339 A a;
340 C() = default;
341 constexpr C(const C&);
342 constexpr C(C&);
344 constexpr C::C(const C&) = default;
345 constexpr C::C(C&) = default; // expected-error {{cannot be marked constexpr}}
348 namespace PR14503 {
349 template<typename> struct V {
350 union {
351 int n;
352 struct {
353 int x,
354 y; // expected-note {{subobject declared here}}
357 constexpr V() : x(0) {}
360 // The constructor is still 'constexpr' here, but the result is not intended
361 // to be a constant expression. The standard is not clear on how this should
362 // work.
363 constexpr V<int> v; // expected-error {{constant expression}} expected-note {{subobject 'y' is not initialized}}
365 constexpr int k = V<int>().x; // FIXME: ok?