blob: b8f57b6c649d6efdb0ffd3fb15688f8dad29e5e5 [file] [log] [blame]
Richard Smith604fb382012-08-07 22:06:48 +00001// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment
Richard Smith59efe262011-11-11 04:05:33 +00002
Richard Smith59efe262011-11-11 04:05:33 +00003namespace StaticAssertFoldTest {
4
5int x;
Richard Smith9eed49c2011-12-09 23:00:37 +00006static_assert(++x, "test"); // expected-error {{not an integral constant expression}}
7static_assert(false, "test"); // expected-error {{test}}
Richard Smith59efe262011-11-11 04:05:33 +00008
9}
10
Richard Smith1d238ea2011-12-21 02:55:12 +000011typedef decltype(sizeof(char)) size_t;
12
13template<typename T> constexpr T id(const T &t) { return t; }
14template<typename T> constexpr T min(const T &a, const T &b) {
15 return a < b ? a : b;
16}
17template<typename T> constexpr T max(const T &a, const T &b) {
18 return a < b ? b : a;
19}
20template<typename T, size_t N> constexpr T *begin(T (&xs)[N]) { return xs; }
21template<typename T, size_t N> constexpr T *end(T (&xs)[N]) { return xs + N; }
Richard Smith59efe262011-11-11 04:05:33 +000022
23struct MemberZero {
Richard Smith84046262013-04-21 01:08:50 +000024 constexpr int zero() const { return 0; }
Richard Smith59efe262011-11-11 04:05:33 +000025};
26
27namespace DerivedToVBaseCast {
28
29 struct U { int n; };
30 struct V : U { int n; };
31 struct A : virtual V { int n; };
32 struct Aa { int n; };
33 struct B : virtual A, Aa {};
34 struct C : virtual A, Aa {};
35 struct D : B, C {};
36
37 D d;
38 constexpr B *p = &d;
39 constexpr C *q = &d;
Richard Smithf15fda02012-02-02 01:16:57 +000040
Richard Smith9eed49c2011-12-09 23:00:37 +000041 static_assert((void*)p != (void*)q, "");
42 static_assert((A*)p == (A*)q, "");
43 static_assert((Aa*)p != (Aa*)q, "");
Richard Smith59efe262011-11-11 04:05:33 +000044
45 constexpr B &pp = d;
46 constexpr C &qq = d;
Richard Smith9eed49c2011-12-09 23:00:37 +000047 static_assert((void*)&pp != (void*)&qq, "");
48 static_assert(&(A&)pp == &(A&)qq, "");
49 static_assert(&(Aa&)pp != &(Aa&)qq, "");
Richard Smith59efe262011-11-11 04:05:33 +000050
51 constexpr V *v = p;
52 constexpr V *w = q;
53 constexpr V *x = (A*)p;
Richard Smith9eed49c2011-12-09 23:00:37 +000054 static_assert(v == w, "");
55 static_assert(v == x, "");
Richard Smith59efe262011-11-11 04:05:33 +000056
Richard Smith9eed49c2011-12-09 23:00:37 +000057 static_assert((U*)&d == p, "");
58 static_assert((U*)&d == q, "");
59 static_assert((U*)&d == v, "");
60 static_assert((U*)&d == w, "");
61 static_assert((U*)&d == x, "");
Richard Smith59efe262011-11-11 04:05:33 +000062
63 struct X {};
64 struct Y1 : virtual X {};
65 struct Y2 : X {};
66 struct Z : Y1, Y2 {};
67 Z z;
Richard Smith9eed49c2011-12-09 23:00:37 +000068 static_assert((X*)(Y1*)&z != (X*)(Y2*)&z, "");
Richard Smith59efe262011-11-11 04:05:33 +000069}
70
Richard Smithf64699e2011-11-11 08:28:03 +000071namespace ConstCast {
72
73constexpr int n1 = 0;
74constexpr int n2 = const_cast<int&>(n1);
75constexpr int *n3 = const_cast<int*>(&n1);
76constexpr int n4 = *const_cast<int*>(&n1);
77constexpr const int * const *n5 = const_cast<const int* const*>(&n3);
78constexpr int **n6 = const_cast<int**>(&n3);
79constexpr int n7 = **n5;
80constexpr int n8 = **n6;
81
82}
83
Richard Smith59efe262011-11-11 04:05:33 +000084namespace TemplateArgumentConversion {
85 template<int n> struct IntParam {};
86
87 using IntParam0 = IntParam<0>;
Richard Smith1d238ea2011-12-21 02:55:12 +000088 using IntParam0 = IntParam<id(0)>;
Richard Smith61802452011-12-22 02:22:31 +000089 using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}}
Richard Smith59efe262011-11-11 04:05:33 +000090}
91
92namespace CaseStatements {
93 void f(int n) {
94 switch (n) {
Richard Smith8ef7b202012-01-18 23:55:52 +000095 case MemberZero().zero: // expected-error {{did you mean to call it with no arguments?}} expected-note {{previous}}
96 case id(0): // expected-error {{duplicate case value '0'}}
Richard Smith59efe262011-11-11 04:05:33 +000097 return;
98 }
99 }
100}
101
102extern int &Recurse1;
Richard Smith16581332012-03-02 04:14:40 +0000103int &Recurse2 = Recurse1; // expected-note {{declared here}}
104int &Recurse1 = Recurse2;
Richard Smith099e7f62011-12-19 06:19:21 +0000105constexpr int &Recurse3 = Recurse2; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'Recurse2' is not a constant expression}}
106
107extern const int RecurseA;
108const int RecurseB = RecurseA; // expected-note {{declared here}}
109const int RecurseA = 10;
110constexpr int RecurseC = RecurseB; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'RecurseB' is not a constant expression}}
Richard Smith59efe262011-11-11 04:05:33 +0000111
112namespace MemberEnum {
113 struct WithMemberEnum {
114 enum E { A = 42 };
115 } wme;
116
Richard Smith9eed49c2011-12-09 23:00:37 +0000117 static_assert(wme.A == 42, "");
Richard Smith59efe262011-11-11 04:05:33 +0000118}
119
120namespace DefaultArguments {
121
122const int z = int();
123constexpr int Sum(int a = 0, const int &b = 0, const int *c = &z, char d = 0) {
124 return a + b + *c + d;
125}
126const int four = 4;
127constexpr int eight = 8;
128constexpr const int twentyseven = 27;
Richard Smith9eed49c2011-12-09 23:00:37 +0000129static_assert(Sum() == 0, "");
130static_assert(Sum(1) == 1, "");
131static_assert(Sum(1, four) == 5, "");
132static_assert(Sum(1, eight, &twentyseven) == 36, "");
133static_assert(Sum(1, 2, &four, eight) == 15, "");
Richard Smith59efe262011-11-11 04:05:33 +0000134
135}
136
137namespace Ellipsis {
138
139// Note, values passed through an ellipsis can't actually be used.
140constexpr int F(int a, ...) { return a; }
Richard Smith9eed49c2011-12-09 23:00:37 +0000141static_assert(F(0) == 0, "");
142static_assert(F(1, 0) == 1, "");
143static_assert(F(2, "test") == 2, "");
144static_assert(F(3, &F) == 3, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000145int k = 0; // expected-note {{here}}
146static_assert(F(4, k) == 3, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'k'}}
Richard Smith59efe262011-11-11 04:05:33 +0000147
148}
149
150namespace Recursion {
151 constexpr int fib(int n) { return n > 1 ? fib(n-1) + fib(n-2) : n; }
Richard Smith9eed49c2011-12-09 23:00:37 +0000152 static_assert(fib(11) == 89, "");
Richard Smith59efe262011-11-11 04:05:33 +0000153
154 constexpr int gcd_inner(int a, int b) {
155 return b == 0 ? a : gcd_inner(b, a % b);
156 }
157 constexpr int gcd(int a, int b) {
158 return gcd_inner(max(a, b), min(a, b));
159 }
160
Richard Smith9eed49c2011-12-09 23:00:37 +0000161 static_assert(gcd(1749237, 5628959) == 7, "");
Richard Smith59efe262011-11-11 04:05:33 +0000162}
163
164namespace FunctionCast {
165 // When folding, we allow functions to be cast to different types. Such
166 // cast functions cannot be called, even if they're constexpr.
167 constexpr int f() { return 1; }
168 typedef double (*DoubleFn)();
169 typedef int (*IntFn)();
Richard Smithd7c56e12011-12-29 21:57:33 +0000170 int a[(int)DoubleFn(f)()]; // expected-error {{variable length array}} expected-warning{{C99 feature}}
Richard Smith59efe262011-11-11 04:05:33 +0000171 int b[(int)IntFn(f)()]; // ok
172}
173
174namespace StaticMemberFunction {
175 struct S {
176 static constexpr int k = 42;
177 static constexpr int f(int n) { return n * k + 2; }
178 } s;
179
180 constexpr int n = s.f(19);
Richard Smith9eed49c2011-12-09 23:00:37 +0000181 static_assert(S::f(19) == 800, "");
182 static_assert(s.f(19) == 800, "");
183 static_assert(n == 800, "");
Richard Smith1bf9a9e2011-11-12 22:28:03 +0000184
185 constexpr int (*sf1)(int) = &S::f;
186 constexpr int (*sf2)(int) = &s.f;
187 constexpr const int *sk = &s.k;
Richard Smith59efe262011-11-11 04:05:33 +0000188}
189
190namespace ParameterScopes {
191
192 const int k = 42;
Richard Smith83587db2012-02-15 02:18:13 +0000193 constexpr const int &ObscureTheTruth(const int &a) { return a; }
Richard Smith099e7f62011-12-19 06:19:21 +0000194 constexpr const int &MaybeReturnJunk(bool b, const int a) { // expected-note 2{{declared here}}
Richard Smith83587db2012-02-15 02:18:13 +0000195 return ObscureTheTruth(b ? a : k);
Richard Smith59efe262011-11-11 04:05:33 +0000196 }
Richard Smith9eed49c2011-12-09 23:00:37 +0000197 static_assert(MaybeReturnJunk(false, 0) == 42, ""); // ok
Richard Smith83587db2012-02-15 02:18:13 +0000198 constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}} expected-note {{read of variable whose lifetime has ended}}
Richard Smith59efe262011-11-11 04:05:33 +0000199
Richard Smith83587db2012-02-15 02:18:13 +0000200 constexpr const int MaybeReturnNonstaticRef(bool b, const int a) {
201 return ObscureTheTruth(b ? a : k);
Richard Smith59efe262011-11-11 04:05:33 +0000202 }
Richard Smith9eed49c2011-12-09 23:00:37 +0000203 static_assert(MaybeReturnNonstaticRef(false, 0) == 42, ""); // ok
Richard Smith83587db2012-02-15 02:18:13 +0000204 constexpr int b = MaybeReturnNonstaticRef(true, 0); // ok
Richard Smith59efe262011-11-11 04:05:33 +0000205
206 constexpr int InternalReturnJunk(int n) {
Richard Smith83587db2012-02-15 02:18:13 +0000207 return MaybeReturnJunk(true, n); // expected-note {{read of variable whose lifetime has ended}}
Richard Smith59efe262011-11-11 04:05:33 +0000208 }
Richard Smith099e7f62011-12-19 06:19:21 +0000209 constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'InternalReturnJunk(0)'}}
Richard Smith59efe262011-11-11 04:05:33 +0000210
211 constexpr int LToR(int &n) { return n; }
212 constexpr int GrabCallersArgument(bool which, int a, int b) {
213 return LToR(which ? b : a);
214 }
Richard Smith9eed49c2011-12-09 23:00:37 +0000215 static_assert(GrabCallersArgument(false, 1, 2) == 1, "");
216 static_assert(GrabCallersArgument(true, 4, 8) == 8, "");
Richard Smith59efe262011-11-11 04:05:33 +0000217
218}
219
220namespace Pointers {
221
222 constexpr int f(int n, const int *a, const int *b, const int *c) {
223 return n == 0 ? 0 : *a + f(n-1, b, c, a);
224 }
225
226 const int x = 1, y = 10, z = 100;
Richard Smith9eed49c2011-12-09 23:00:37 +0000227 static_assert(f(23, &x, &y, &z) == 788, "");
Richard Smith59efe262011-11-11 04:05:33 +0000228
229 constexpr int g(int n, int a, int b, int c) {
230 return f(n, &a, &b, &c);
231 }
Richard Smith9eed49c2011-12-09 23:00:37 +0000232 static_assert(g(23, x, y, z) == 788, "");
Richard Smith59efe262011-11-11 04:05:33 +0000233
234}
235
236namespace FunctionPointers {
237
238 constexpr int Double(int n) { return 2 * n; }
239 constexpr int Triple(int n) { return 3 * n; }
240 constexpr int Twice(int (*F)(int), int n) { return F(F(n)); }
241 constexpr int Quadruple(int n) { return Twice(Double, n); }
242 constexpr auto Select(int n) -> int (*)(int) {
243 return n == 2 ? &Double : n == 3 ? &Triple : n == 4 ? &Quadruple : 0;
244 }
Richard Smith099e7f62011-12-19 06:19:21 +0000245 constexpr int Apply(int (*F)(int), int n) { return F(n); } // expected-note {{subexpression}}
Richard Smith59efe262011-11-11 04:05:33 +0000246
Richard Smith9eed49c2011-12-09 23:00:37 +0000247 static_assert(1 + Apply(Select(4), 5) + Apply(Select(3), 7) == 42, "");
Richard Smith59efe262011-11-11 04:05:33 +0000248
Richard Smith099e7f62011-12-19 06:19:21 +0000249 constexpr int Invalid = Apply(Select(0), 0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'Apply(0, 0)'}}
Richard Smith59efe262011-11-11 04:05:33 +0000250
251}
252
253namespace PointerComparison {
254
255int x, y;
Richard Smith9eed49c2011-12-09 23:00:37 +0000256static_assert(&x == &y, "false"); // expected-error {{false}}
257static_assert(&x != &y, "");
Richard Smith59efe262011-11-11 04:05:33 +0000258constexpr bool g1 = &x == &y;
259constexpr bool g2 = &x != &y;
260constexpr bool g3 = &x <= &y; // expected-error {{must be initialized by a constant expression}}
261constexpr bool g4 = &x >= &y; // expected-error {{must be initialized by a constant expression}}
262constexpr bool g5 = &x < &y; // expected-error {{must be initialized by a constant expression}}
263constexpr bool g6 = &x > &y; // expected-error {{must be initialized by a constant expression}}
264
265struct S { int x, y; } s;
Richard Smith9eed49c2011-12-09 23:00:37 +0000266static_assert(&s.x == &s.y, "false"); // expected-error {{false}}
267static_assert(&s.x != &s.y, "");
268static_assert(&s.x <= &s.y, "");
269static_assert(&s.x >= &s.y, "false"); // expected-error {{false}}
270static_assert(&s.x < &s.y, "");
271static_assert(&s.x > &s.y, "false"); // expected-error {{false}}
Richard Smith59efe262011-11-11 04:05:33 +0000272
Richard Smith9eed49c2011-12-09 23:00:37 +0000273static_assert(0 == &y, "false"); // expected-error {{false}}
274static_assert(0 != &y, "");
Richard Smith59efe262011-11-11 04:05:33 +0000275constexpr bool n3 = 0 <= &y; // expected-error {{must be initialized by a constant expression}}
276constexpr bool n4 = 0 >= &y; // expected-error {{must be initialized by a constant expression}}
277constexpr bool n5 = 0 < &y; // expected-error {{must be initialized by a constant expression}}
278constexpr bool n6 = 0 > &y; // expected-error {{must be initialized by a constant expression}}
279
Richard Smith9eed49c2011-12-09 23:00:37 +0000280static_assert(&x == 0, "false"); // expected-error {{false}}
281static_assert(&x != 0, "");
Richard Smith59efe262011-11-11 04:05:33 +0000282constexpr bool n9 = &x <= 0; // expected-error {{must be initialized by a constant expression}}
283constexpr bool n10 = &x >= 0; // expected-error {{must be initialized by a constant expression}}
284constexpr bool n11 = &x < 0; // expected-error {{must be initialized by a constant expression}}
285constexpr bool n12 = &x > 0; // expected-error {{must be initialized by a constant expression}}
286
Richard Smith9eed49c2011-12-09 23:00:37 +0000287static_assert(&x == &x, "");
288static_assert(&x != &x, "false"); // expected-error {{false}}
289static_assert(&x <= &x, "");
290static_assert(&x >= &x, "");
291static_assert(&x < &x, "false"); // expected-error {{false}}
292static_assert(&x > &x, "false"); // expected-error {{false}}
Richard Smith59efe262011-11-11 04:05:33 +0000293
294constexpr S* sptr = &s;
Richard Smith099e7f62011-12-19 06:19:21 +0000295constexpr bool dyncast = sptr == dynamic_cast<S*>(sptr); // expected-error {{constant expression}} expected-note {{dynamic_cast}}
Richard Smith59efe262011-11-11 04:05:33 +0000296
Richard Smith2fd59832012-02-08 08:11:33 +0000297struct U {};
Richard Smithc216a012011-12-12 12:46:16 +0000298struct Str {
Richard Smithc216a012011-12-12 12:46:16 +0000299 int a : dynamic_cast<S*>(sptr) == dynamic_cast<S*>(sptr); // \
Richard Smith244ee7b2012-01-15 03:51:30 +0000300 expected-warning {{not an integral constant expression}} \
Richard Smith4cd9b8f2011-12-12 19:10:03 +0000301 expected-note {{dynamic_cast is not allowed in a constant expression}}
Richard Smithc216a012011-12-12 12:46:16 +0000302 int b : reinterpret_cast<S*>(sptr) == reinterpret_cast<S*>(sptr); // \
Richard Smith244ee7b2012-01-15 03:51:30 +0000303 expected-warning {{not an integral constant expression}} \
Richard Smith4cd9b8f2011-12-12 19:10:03 +0000304 expected-note {{reinterpret_cast is not allowed in a constant expression}}
Richard Smithc216a012011-12-12 12:46:16 +0000305 int c : (S*)(long)(sptr) == (S*)(long)(sptr); // \
Richard Smith244ee7b2012-01-15 03:51:30 +0000306 expected-warning {{not an integral constant expression}} \
Richard Smith60f24e72011-12-12 19:33:27 +0000307 expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
Richard Smithc216a012011-12-12 12:46:16 +0000308 int d : (S*)(42) == (S*)(42); // \
Richard Smith244ee7b2012-01-15 03:51:30 +0000309 expected-warning {{not an integral constant expression}} \
Richard Smith60f24e72011-12-12 19:33:27 +0000310 expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
Richard Smithc216a012011-12-12 12:46:16 +0000311 int e : (Str*)(sptr) == (Str*)(sptr); // \
Richard Smith244ee7b2012-01-15 03:51:30 +0000312 expected-warning {{not an integral constant expression}} \
Richard Smith60f24e72011-12-12 19:33:27 +0000313 expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
Richard Smith2fd59832012-02-08 08:11:33 +0000314 int f : &(U&)(*sptr) == &(U&)(*sptr); // \
Richard Smith244ee7b2012-01-15 03:51:30 +0000315 expected-warning {{not an integral constant expression}} \
Richard Smith60f24e72011-12-12 19:33:27 +0000316 expected-note {{cast which performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
Richard Smithc216a012011-12-12 12:46:16 +0000317 int g : (S*)(void*)(sptr) == sptr; // \
Richard Smith244ee7b2012-01-15 03:51:30 +0000318 expected-warning {{not an integral constant expression}} \
Richard Smith4cd9b8f2011-12-12 19:10:03 +0000319 expected-note {{cast from 'void *' is not allowed in a constant expression}}
Richard Smithc216a012011-12-12 12:46:16 +0000320};
321
Richard Smith59efe262011-11-11 04:05:33 +0000322extern char externalvar[];
Richard Smith9eed49c2011-12-09 23:00:37 +0000323constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; // expected-error {{must be initialized by a constant expression}}
Richard Smith59efe262011-11-11 04:05:33 +0000324constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} expected-warning {{unspecified}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000325static_assert(0 != "foo", "");
Richard Smith59efe262011-11-11 04:05:33 +0000326
327}
328
329namespace MaterializeTemporary {
330
331constexpr int f(const int &r) { return r; }
332constexpr int n = f(1);
333
334constexpr bool same(const int &a, const int &b) { return &a == &b; }
335constexpr bool sameTemporary(const int &n) { return same(n, n); }
336
Richard Smith9eed49c2011-12-09 23:00:37 +0000337static_assert(n, "");
338static_assert(!same(4, 4), "");
339static_assert(same(n, n), "");
340static_assert(sameTemporary(9), "");
Richard Smith59efe262011-11-11 04:05:33 +0000341
342}
343
344constexpr int strcmp_ce(const char *p, const char *q) {
345 return (!*p || *p != *q) ? *p - *q : strcmp_ce(p+1, q+1);
346}
347
348namespace StringLiteral {
349
Richard Smith1d238ea2011-12-21 02:55:12 +0000350template<typename Char>
351constexpr int MangleChars(const Char *p) {
Richard Smith59efe262011-11-11 04:05:33 +0000352 return *p + 3 * (*p ? MangleChars(p+1) : 0);
353}
354
Richard Smith9eed49c2011-12-09 23:00:37 +0000355static_assert(MangleChars("constexpr!") == 1768383, "");
Richard Smithec789162012-01-12 18:54:33 +0000356static_assert(MangleChars(u8"constexpr!") == 1768383, "");
357static_assert(MangleChars(L"constexpr!") == 1768383, "");
Richard Smith9eed49c2011-12-09 23:00:37 +0000358static_assert(MangleChars(u"constexpr!") == 1768383, "");
359static_assert(MangleChars(U"constexpr!") == 1768383, "");
Richard Smith59efe262011-11-11 04:05:33 +0000360
361constexpr char c0 = "nought index"[0];
362constexpr char c1 = "nice index"[10];
Richard Smith7098cbd2011-12-21 05:04:46 +0000363constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is past the end}} expected-note {{read of dereferenced one-past-the-end pointer}}
Richard Smithb4e85ed2012-01-06 16:39:00 +0000364constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is before the beginning}} expected-note {{cannot refer to element -1 of array of 15 elements}}
365constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast which performs the conversions of a reinterpret_cast}}
Richard Smith59efe262011-11-11 04:05:33 +0000366
367constexpr const char *p = "test" + 2;
Richard Smith9eed49c2011-12-09 23:00:37 +0000368static_assert(*p == 's', "");
Richard Smith59efe262011-11-11 04:05:33 +0000369
370constexpr const char *max_iter(const char *a, const char *b) {
371 return *a < *b ? b : a;
372}
373constexpr const char *max_element(const char *a, const char *b) {
374 return (a+1 >= b) ? a : max_iter(a, max_element(a+1, b));
375}
376
Richard Smith59efe262011-11-11 04:05:33 +0000377constexpr char str[] = "the quick brown fox jumped over the lazy dog";
378constexpr const char *max = max_element(begin(str), end(str));
Richard Smith9eed49c2011-12-09 23:00:37 +0000379static_assert(*max == 'z', "");
380static_assert(max == str + 38, "");
Richard Smith59efe262011-11-11 04:05:33 +0000381
Richard Smith9eed49c2011-12-09 23:00:37 +0000382static_assert(strcmp_ce("hello world", "hello world") == 0, "");
383static_assert(strcmp_ce("hello world", "hello clang") > 0, "");
384static_assert(strcmp_ce("constexpr", "test") < 0, "");
385static_assert(strcmp_ce("", " ") < 0, "");
Richard Smith59efe262011-11-11 04:05:33 +0000386
Richard Smith7098cbd2011-12-21 05:04:46 +0000387struct S {
388 int n : "foo"[4]; // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer is not allowed in a constant expression}}
389};
390
Richard Smith974c5f92011-12-22 01:07:19 +0000391struct T {
392 char c[6];
393 constexpr T() : c{"foo"} {}
394};
395constexpr T t;
396
397static_assert(t.c[0] == 'f', "");
398static_assert(t.c[1] == 'o', "");
399static_assert(t.c[2] == 'o', "");
400static_assert(t.c[3] == 0, "");
401static_assert(t.c[4] == 0, "");
402static_assert(t.c[5] == 0, "");
403static_assert(t.c[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
404
Richard Smithec789162012-01-12 18:54:33 +0000405struct U {
406 wchar_t chars[6];
407 int n;
408} constexpr u = { { L"test" }, 0 };
409static_assert(u.chars[2] == L's', "");
410
Richard Smithf3908f22012-02-17 03:35:37 +0000411struct V {
412 char c[4];
413 constexpr V() : c("hi!") {}
414};
415static_assert(V().c[1] == "i"[0], "");
416
Richard Smith59efe262011-11-11 04:05:33 +0000417}
418
419namespace Array {
420
Richard Smith1d238ea2011-12-21 02:55:12 +0000421template<typename Iter>
422constexpr auto Sum(Iter begin, Iter end) -> decltype(+*begin) {
Richard Smith59efe262011-11-11 04:05:33 +0000423 return begin == end ? 0 : *begin + Sum(begin+1, end);
424}
Richard Smith59efe262011-11-11 04:05:33 +0000425
426constexpr int xs[] = { 1, 2, 3, 4, 5 };
427constexpr int ys[] = { 5, 4, 3, 2, 1 };
428constexpr int sum_xs = Sum(begin(xs), end(xs));
Richard Smith9eed49c2011-12-09 23:00:37 +0000429static_assert(sum_xs == 15, "");
Richard Smith59efe262011-11-11 04:05:33 +0000430
431constexpr int ZipFoldR(int (*F)(int x, int y, int c), int n,
432 const int *xs, const int *ys, int c) {
Richard Smithdaaefc52011-12-14 23:32:26 +0000433 return n ? F(
Richard Smith7098cbd2011-12-21 05:04:46 +0000434 *xs, // expected-note {{read of dereferenced one-past-the-end pointer}}
Richard Smith08d6e032011-12-16 19:06:07 +0000435 *ys,
436 ZipFoldR(F, n-1, xs+1, ys+1, c)) // \
437 expected-note {{in call to 'ZipFoldR(&SubMul, 2, &xs[4], &ys[4], 1)'}} \
438 expected-note {{in call to 'ZipFoldR(&SubMul, 1, &xs[5], &ys[5], 1)'}}
439 : c;
Richard Smith59efe262011-11-11 04:05:33 +0000440}
441constexpr int MulAdd(int x, int y, int c) { return x * y + c; }
442constexpr int InnerProduct = ZipFoldR(MulAdd, 5, xs, ys, 0);
Richard Smith9eed49c2011-12-09 23:00:37 +0000443static_assert(InnerProduct == 35, "");
Richard Smith59efe262011-11-11 04:05:33 +0000444
445constexpr int SubMul(int x, int y, int c) { return (x - y) * c; }
446constexpr int DiffProd = ZipFoldR(SubMul, 2, xs+3, ys+3, 1);
Richard Smith9eed49c2011-12-09 23:00:37 +0000447static_assert(DiffProd == 8, "");
Richard Smith08d6e032011-12-16 19:06:07 +0000448static_assert(ZipFoldR(SubMul, 3, xs+3, ys+3, 1), ""); // \
449 expected-error {{constant expression}} \
450 expected-note {{in call to 'ZipFoldR(&SubMul, 3, &xs[3], &ys[3], 1)'}}
Richard Smith59efe262011-11-11 04:05:33 +0000451
452constexpr const int *p = xs + 3;
453constexpr int xs4 = p[1]; // ok
Richard Smith7098cbd2011-12-21 05:04:46 +0000454constexpr int xs5 = p[2]; // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
Richard Smithb4e85ed2012-01-06 16:39:00 +0000455constexpr int xs6 = p[3]; // expected-error {{constant expression}} expected-note {{cannot refer to element 6}}
Richard Smith59efe262011-11-11 04:05:33 +0000456constexpr int xs0 = p[-3]; // ok
Richard Smithb4e85ed2012-01-06 16:39:00 +0000457constexpr int xs_1 = p[-4]; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
Richard Smith59efe262011-11-11 04:05:33 +0000458
459constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
Richard Smith9eed49c2011-12-09 23:00:37 +0000460static_assert(zs[0][0][0][0] == 1, "");
461static_assert(zs[1][1][1][1] == 16, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000462static_assert(zs[0][0][0][2] == 3, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000463static_assert((&zs[0][0][0][2])[-1] == 2, "");
464static_assert(**(**(zs + 1) + 1) == 11, "");
Richard Smithb4e85ed2012-01-06 16:39:00 +0000465static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][-1] + 1) == 11, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element -1 of array of 2 elements in a constant expression}}
466static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2) == 11, "");
467constexpr int err_zs_1_2_0_0 = zs[1][2][0][0]; // expected-error {{constant expression}} expected-note {{cannot access array element of pointer past the end}}
Richard Smith59efe262011-11-11 04:05:33 +0000468
Richard Smith08d6e032011-12-16 19:06:07 +0000469constexpr int fail(const int &p) {
Richard Smithb4e85ed2012-01-06 16:39:00 +0000470 return (&p)[64]; // expected-note {{cannot refer to element 64 of array of 2 elements}}
Richard Smith08d6e032011-12-16 19:06:07 +0000471}
Richard Smithb4e85ed2012-01-06 16:39:00 +0000472static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2)) == 11, ""); // \
Richard Smith08d6e032011-12-16 19:06:07 +0000473expected-error {{static_assert expression is not an integral constant expression}} \
474expected-note {{in call to 'fail(zs[1][0][1][0])'}}
475
Richard Smithd7c56e12011-12-29 21:57:33 +0000476constexpr int arr[40] = { 1, 2, 3, [8] = 4 }; // expected-warning {{C99 feature}}
Richard Smith59efe262011-11-11 04:05:33 +0000477constexpr int SumNonzero(const int *p) {
478 return *p + (*p ? SumNonzero(p+1) : 0);
479}
480constexpr int CountZero(const int *p, const int *q) {
481 return p == q ? 0 : (*p == 0) + CountZero(p+1, q);
482}
Richard Smith9eed49c2011-12-09 23:00:37 +0000483static_assert(SumNonzero(arr) == 6, "");
484static_assert(CountZero(arr, arr + 40) == 36, "");
Richard Smith59efe262011-11-11 04:05:33 +0000485
Richard Smithe24f5fc2011-11-17 22:56:20 +0000486struct ArrayElem {
487 constexpr ArrayElem() : n(0) {}
488 int n;
Richard Smith84046262013-04-21 01:08:50 +0000489 constexpr int f() const { return n; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000490};
491struct ArrayRVal {
492 constexpr ArrayRVal() {}
493 ArrayElem elems[10];
494};
Richard Smith9eed49c2011-12-09 23:00:37 +0000495static_assert(ArrayRVal().elems[3].f() == 0, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000496
Richard Smithde31aa72012-07-07 22:48:24 +0000497constexpr int selfref[2][2][2] = {
498 selfref[1][1][1] + 1, selfref[0][0][0] + 1,
499 selfref[1][0][1] + 1, selfref[0][1][0] + 1,
500 selfref[1][0][0] + 1, selfref[0][1][1] + 1 };
501static_assert(selfref[0][0][0] == 1, "");
502static_assert(selfref[0][0][1] == 2, "");
503static_assert(selfref[0][1][0] == 1, "");
504static_assert(selfref[0][1][1] == 2, "");
505static_assert(selfref[1][0][0] == 1, "");
506static_assert(selfref[1][0][1] == 3, "");
507static_assert(selfref[1][1][0] == 0, "");
508static_assert(selfref[1][1][1] == 0, "");
509
Richard Smitha4334df2012-07-10 22:12:55 +0000510struct TrivialDefCtor { int n; };
511typedef TrivialDefCtor TDCArray[2][2];
512static_assert(TDCArray{}[1][1].n == 0, "");
513
514struct NonAggregateTDC : TrivialDefCtor {};
515typedef NonAggregateTDC NATDCArray[2][2];
516static_assert(NATDCArray{}[1][1].n == 0, "");
517
Richard Smith59efe262011-11-11 04:05:33 +0000518}
519
520namespace DependentValues {
521
522struct I { int n; typedef I V[10]; };
523I::V x, y;
Richard Smith9568f0c2012-10-29 18:26:47 +0000524int g();
Richard Smith1432a432012-10-28 06:18:02 +0000525template<bool B, typename T> struct S : T {
Richard Smith59efe262011-11-11 04:05:33 +0000526 int k;
527 void f() {
528 I::V &cells = B ? x : y;
529 I &i = cells[k];
530 switch (i.n) {}
Richard Smith1432a432012-10-28 06:18:02 +0000531
Richard Smith9568f0c2012-10-29 18:26:47 +0000532 // FIXME: We should be able to diagnose this.
533 constexpr int n = g();
Richard Smith1432a432012-10-28 06:18:02 +0000534
535 constexpr int m = this->g(); // ok, could be constexpr
Richard Smith59efe262011-11-11 04:05:33 +0000536 }
537};
538
539}
540
541namespace Class {
542
543struct A { constexpr A(int a, int b) : k(a + b) {} int k; };
544constexpr int fn(const A &a) { return a.k; }
Richard Smith9eed49c2011-12-09 23:00:37 +0000545static_assert(fn(A(4,5)) == 9, "");
Richard Smith59efe262011-11-11 04:05:33 +0000546
547struct B { int n; int m; } constexpr b = { 0, b.n }; // expected-warning {{uninitialized}}
548struct C {
549 constexpr C(C *this_) : m(42), n(this_->m) {} // ok
550 int m, n;
551};
552struct D {
553 C c;
554 constexpr D() : c(&c) {}
555};
Richard Smith9eed49c2011-12-09 23:00:37 +0000556static_assert(D().c.n == 42, "");
Richard Smith59efe262011-11-11 04:05:33 +0000557
Richard Smith61802452011-12-22 02:22:31 +0000558struct E {
Richard Smith83587db2012-02-15 02:18:13 +0000559 constexpr E() : p(&p) {}
Richard Smith59efe262011-11-11 04:05:33 +0000560 void *p;
561};
Richard Smith83587db2012-02-15 02:18:13 +0000562constexpr const E &e1 = E(); // expected-error {{constant expression}} expected-note {{reference to temporary is not a constant expression}} expected-note {{temporary created here}}
Richard Smith59efe262011-11-11 04:05:33 +0000563// This is a constant expression if we elide the copy constructor call, and
564// is not a constant expression if we don't! But we do, so it is.
Richard Smith61802452011-12-22 02:22:31 +0000565constexpr E e2 = E();
566static_assert(e2.p == &e2.p, "");
Richard Smith099e7f62011-12-19 06:19:21 +0000567constexpr E e3;
Richard Smith9eed49c2011-12-09 23:00:37 +0000568static_assert(e3.p == &e3.p, "");
Richard Smith59efe262011-11-11 04:05:33 +0000569
570extern const class F f;
571struct F {
572 constexpr F() : p(&f.p) {}
573 const void *p;
574};
Richard Smith099e7f62011-12-19 06:19:21 +0000575constexpr F f;
Richard Smith59efe262011-11-11 04:05:33 +0000576
577struct G {
578 struct T {
579 constexpr T(T *p) : u1(), u2(p) {}
580 union U1 {
581 constexpr U1() {}
582 int a, b = 42;
583 } u1;
584 union U2 {
585 constexpr U2(T *p) : c(p->u1.b) {}
586 int c, d;
587 } u2;
588 } t;
589 constexpr G() : t(&t) {}
590} constexpr g;
591
Richard Smith7098cbd2011-12-21 05:04:46 +0000592static_assert(g.t.u1.a == 42, ""); // expected-error {{constant expression}} expected-note {{read of member 'a' of union with active member 'b'}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000593static_assert(g.t.u1.b == 42, "");
594static_assert(g.t.u2.c == 42, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000595static_assert(g.t.u2.d == 42, ""); // expected-error {{constant expression}} expected-note {{read of member 'd' of union with active member 'c'}}
Richard Smith59efe262011-11-11 04:05:33 +0000596
597struct S {
598 int a, b;
599 const S *p;
600 double d;
601 const char *q;
602
603 constexpr S(int n, const S *p) : a(5), b(n), p(p), d(n), q("hello") {}
604};
605
606S global(43, &global);
607
Richard Smith9eed49c2011-12-09 23:00:37 +0000608static_assert(S(15, &global).b == 15, "");
Richard Smith59efe262011-11-11 04:05:33 +0000609
610constexpr bool CheckS(const S &s) {
611 return s.a == 5 && s.b == 27 && s.p == &global && s.d == 27. && s.q[3] == 'l';
612}
Richard Smith9eed49c2011-12-09 23:00:37 +0000613static_assert(CheckS(S(27, &global)), "");
Richard Smith59efe262011-11-11 04:05:33 +0000614
615struct Arr {
616 char arr[3];
617 constexpr Arr() : arr{'x', 'y', 'z'} {}
618};
619constexpr int hash(Arr &&a) {
620 return a.arr[0] + a.arr[1] * 0x100 + a.arr[2] * 0x10000;
621}
622constexpr int k = hash(Arr());
Richard Smith9eed49c2011-12-09 23:00:37 +0000623static_assert(k == 0x007a7978, "");
Richard Smith59efe262011-11-11 04:05:33 +0000624
625
626struct AggregateInit {
627 const char &c;
628 int n;
629 double d;
630 int arr[5];
631 void *p;
632};
633
634constexpr AggregateInit agg1 = { "hello"[0] };
635
Richard Smith9eed49c2011-12-09 23:00:37 +0000636static_assert(strcmp_ce(&agg1.c, "hello") == 0, "");
637static_assert(agg1.n == 0, "");
638static_assert(agg1.d == 0.0, "");
Richard Smithb4e85ed2012-01-06 16:39:00 +0000639static_assert(agg1.arr[-1] == 0, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000640static_assert(agg1.arr[0] == 0, "");
641static_assert(agg1.arr[4] == 0, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000642static_assert(agg1.arr[5] == 0, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000643static_assert(agg1.p == nullptr, "");
Richard Smith59efe262011-11-11 04:05:33 +0000644
Richard Smithfe587202012-04-15 02:50:59 +0000645static constexpr const unsigned char uc[] = { "foo" };
646static_assert(uc[0] == 'f', "");
647static_assert(uc[3] == 0, "");
648
Richard Smith59efe262011-11-11 04:05:33 +0000649namespace SimpleDerivedClass {
650
651struct B {
652 constexpr B(int n) : a(n) {}
653 int a;
654};
655struct D : B {
656 constexpr D(int n) : B(n) {}
657};
658constexpr D d(3);
Richard Smith9eed49c2011-12-09 23:00:37 +0000659static_assert(d.a == 3, "");
Richard Smith59efe262011-11-11 04:05:33 +0000660
661}
662
Richard Smithe24f5fc2011-11-17 22:56:20 +0000663struct Bottom { constexpr Bottom() {} };
664struct Base : Bottom {
Richard Smith59efe262011-11-11 04:05:33 +0000665 constexpr Base(int a = 42, const char *b = "test") : a(a), b(b) {}
666 int a;
667 const char *b;
668};
Richard Smithe24f5fc2011-11-17 22:56:20 +0000669struct Base2 : Bottom {
Richard Smith59efe262011-11-11 04:05:33 +0000670 constexpr Base2(const int &r) : r(r) {}
671 int q = 123;
Richard Smith099e7f62011-12-19 06:19:21 +0000672 const int &r;
Richard Smith59efe262011-11-11 04:05:33 +0000673};
674struct Derived : Base, Base2 {
675 constexpr Derived() : Base(76), Base2(a) {}
676 int c = r + b[1];
677};
678
679constexpr bool operator==(const Base &a, const Base &b) {
680 return a.a == b.a && strcmp_ce(a.b, b.b) == 0;
681}
682
683constexpr Base base;
684constexpr Base base2(76);
685constexpr Derived derived;
Richard Smith9eed49c2011-12-09 23:00:37 +0000686static_assert(derived.a == 76, "");
687static_assert(derived.b[2] == 's', "");
688static_assert(derived.c == 76 + 'e', "");
689static_assert(derived.q == 123, "");
690static_assert(derived.r == 76, "");
Richard Smith099e7f62011-12-19 06:19:21 +0000691static_assert(&derived.r == &derived.a, "");
Richard Smith59efe262011-11-11 04:05:33 +0000692
Richard Smith9eed49c2011-12-09 23:00:37 +0000693static_assert(!(derived == base), "");
694static_assert(derived == base2, "");
Richard Smith59efe262011-11-11 04:05:33 +0000695
Richard Smithe24f5fc2011-11-17 22:56:20 +0000696constexpr Bottom &bot1 = (Base&)derived;
697constexpr Bottom &bot2 = (Base2&)derived;
Richard Smith9eed49c2011-12-09 23:00:37 +0000698static_assert(&bot1 != &bot2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000699
700constexpr Bottom *pb1 = (Base*)&derived;
701constexpr Bottom *pb2 = (Base2*)&derived;
Richard Smithf15fda02012-02-02 01:16:57 +0000702static_assert(&pb1 != &pb2, "");
Richard Smith9eed49c2011-12-09 23:00:37 +0000703static_assert(pb1 == &bot1, "");
704static_assert(pb2 == &bot2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000705
Richard Smithb4e85ed2012-01-06 16:39:00 +0000706constexpr Base2 &fail = (Base2&)bot1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}}
707constexpr Base &fail2 = (Base&)*pb2; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base'}}
Richard Smithe24f5fc2011-11-17 22:56:20 +0000708constexpr Base2 &ok2 = (Base2&)bot2;
Richard Smith9eed49c2011-12-09 23:00:37 +0000709static_assert(&ok2 == &derived, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000710
Richard Smithb4e85ed2012-01-06 16:39:00 +0000711constexpr Base2 *pfail = (Base2*)pb1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}}
712constexpr Base *pfail2 = (Base*)&bot2; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base'}}
Richard Smithe24f5fc2011-11-17 22:56:20 +0000713constexpr Base2 *pok2 = (Base2*)pb2;
Richard Smith9eed49c2011-12-09 23:00:37 +0000714static_assert(pok2 == &derived, "");
715static_assert(&ok2 == pok2, "");
716static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");
717static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000718
David Blaikie50800fc2012-08-08 17:33:31 +0000719constexpr Base *nullB = 42 - 6 * 7; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *const'}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000720static_assert((Bottom*)nullB == 0, "");
721static_assert((Derived*)nullB == 0, "");
722static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");
David Blaikie50800fc2012-08-08 17:33:31 +0000723Base * nullB2 = '\0'; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *'}}
724Base * nullB3 = (0);
725// We suppress the warning in unevaluated contexts to workaround some gtest
726// behavior. Once this becomes an error this isn't a problem anymore.
727static_assert(nullB == (1 - 1), "");
728
Richard Smithe24f5fc2011-11-17 22:56:20 +0000729
Richard Smith7d580a42012-01-17 21:17:26 +0000730namespace ConversionOperators {
731
732struct T {
733 constexpr T(int n) : k(5*n - 3) {}
Richard Smith84046262013-04-21 01:08:50 +0000734 constexpr operator int() const { return k; }
Richard Smith7d580a42012-01-17 21:17:26 +0000735 int k;
736};
737
738struct S {
739 constexpr S(int n) : k(2*n + 1) {}
Richard Smith84046262013-04-21 01:08:50 +0000740 constexpr operator int() const { return k; }
741 constexpr operator T() const { return T(k); }
Richard Smith7d580a42012-01-17 21:17:26 +0000742 int k;
743};
744
745constexpr bool check(T a, T b) { return a == b.k; }
746
747static_assert(S(5) == 11, "");
748static_assert(check(S(5), 11), "");
749
Richard Smithe9253222012-10-24 23:51:56 +0000750namespace PR14171 {
751
752struct X {
Richard Smith84046262013-04-21 01:08:50 +0000753 constexpr (operator int)() const { return 0; }
Richard Smithe9253222012-10-24 23:51:56 +0000754};
755static_assert(X() == 0, "");
756
757}
758
Richard Smith7d580a42012-01-17 21:17:26 +0000759}
760
Richard Smithe24f5fc2011-11-17 22:56:20 +0000761}
762
763namespace Temporaries {
764
765struct S {
766 constexpr S() {}
Richard Smith84046262013-04-21 01:08:50 +0000767 constexpr int f() const;
Richard Smithe24f5fc2011-11-17 22:56:20 +0000768};
769struct T : S {
770 constexpr T(int n) : S(), n(n) {}
771 int n;
772};
Richard Smith84046262013-04-21 01:08:50 +0000773constexpr int S::f() const {
Richard Smithe24f5fc2011-11-17 22:56:20 +0000774 // 'this' must be the postfix-expression in a class member access expression,
775 // so we can't just use
776 // return static_cast<T*>(this)->n;
777 return this->*(int(S::*))&T::n;
778}
779// The T temporary is implicitly cast to an S subobject, but we can recover the
780// T full-object via a base-to-derived cast, or a derived-to-base-casted member
781// pointer.
Richard Smith9eed49c2011-12-09 23:00:37 +0000782static_assert(T(3).f() == 3, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000783
784constexpr int f(const S &s) {
785 return static_cast<const T&>(s).n;
786}
787constexpr int n = f(T(5));
Richard Smith9eed49c2011-12-09 23:00:37 +0000788static_assert(f(T(5)) == 5, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000789
Richard Smithf2e4cd72012-01-26 04:47:34 +0000790constexpr bool b(int n) { return &n; }
791static_assert(b(0), "");
792
Richard Smith59efe262011-11-11 04:05:33 +0000793}
794
795namespace Union {
796
797union U {
798 int a;
799 int b;
800};
801
Richard Smithd7c56e12011-12-29 21:57:33 +0000802constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } }; // expected-warning 4{{C99 feature}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000803static_assert(u[0].a == 0, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000804static_assert(u[0].b, ""); // expected-error {{constant expression}} expected-note {{read of member 'b' of union with active member 'a'}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000805static_assert(u[1].b == 1, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000806static_assert((&u[1].b)[1] == 2, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
Richard Smithb4e85ed2012-01-06 16:39:00 +0000807static_assert(*(&(u[1].b) + 1 + 1) == 3, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element 2 of non-array object}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000808static_assert((&(u[1]) + 1 + 1)->b == 3, "");
Richard Smith59efe262011-11-11 04:05:33 +0000809
Richard Smithec789162012-01-12 18:54:33 +0000810constexpr U v = {};
811static_assert(v.a == 0, "");
812
813union Empty {};
814constexpr Empty e = {};
815
Richard Smith610a60c2012-01-10 04:32:03 +0000816// Make sure we handle trivial copy constructors for unions.
817constexpr U x = {42};
818constexpr U y = x;
819static_assert(y.a == 42, "");
820static_assert(y.b == 42, ""); // expected-error {{constant expression}} expected-note {{'b' of union with active member 'a'}}
821
Richard Smith59efe262011-11-11 04:05:33 +0000822}
823
Richard Smithe24f5fc2011-11-17 22:56:20 +0000824namespace MemberPointer {
825 struct A {
826 constexpr A(int n) : n(n) {}
827 int n;
Richard Smith84046262013-04-21 01:08:50 +0000828 constexpr int f() const { return n + 3; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000829 };
830 constexpr A a(7);
Richard Smith9eed49c2011-12-09 23:00:37 +0000831 static_assert(A(5).*&A::n == 5, "");
832 static_assert((&a)->*&A::n == 7, "");
833 static_assert((A(8).*&A::f)() == 11, "");
834 static_assert(((&a)->*&A::f)() == 10, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000835
836 struct B : A {
837 constexpr B(int n, int m) : A(n), m(m) {}
838 int m;
Richard Smith84046262013-04-21 01:08:50 +0000839 constexpr int g() const { return n + m + 1; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000840 };
841 constexpr B b(9, 13);
Richard Smith9eed49c2011-12-09 23:00:37 +0000842 static_assert(B(4, 11).*&A::n == 4, "");
843 static_assert(B(4, 11).*&B::m == 11, "");
844 static_assert(B(4, 11).*(int(A::*))&B::m == 11, "");
845 static_assert((&b)->*&A::n == 9, "");
846 static_assert((&b)->*&B::m == 13, "");
847 static_assert((&b)->*(int(A::*))&B::m == 13, "");
848 static_assert((B(4, 11).*&A::f)() == 7, "");
849 static_assert((B(4, 11).*&B::g)() == 16, "");
850 static_assert((B(4, 11).*(int(A::*)()const)&B::g)() == 16, "");
851 static_assert(((&b)->*&A::f)() == 12, "");
852 static_assert(((&b)->*&B::g)() == 23, "");
853 static_assert(((&b)->*(int(A::*)()const)&B::g)() == 23, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000854
855 struct S {
856 constexpr S(int m, int n, int (S::*pf)() const, int S::*pn) :
857 m(m), n(n), pf(pf), pn(pn) {}
858 constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {}
859
Richard Smith84046262013-04-21 01:08:50 +0000860 constexpr int f() const { return this->*pn; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000861 virtual int g() const;
862
863 int m, n;
864 int (S::*pf)() const;
865 int S::*pn;
866 };
867
868 constexpr int S::*pm = &S::m;
869 constexpr int S::*pn = &S::n;
870 constexpr int (S::*pf)() const = &S::f;
871 constexpr int (S::*pg)() const = &S::g;
872
873 constexpr S s(2, 5, &S::f, &S::m);
874
Richard Smith9eed49c2011-12-09 23:00:37 +0000875 static_assert((s.*&S::f)() == 2, "");
876 static_assert((s.*s.pf)() == 2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000877
Richard Smithb02e4622012-02-01 01:42:44 +0000878 static_assert(pf == &S::f, "");
879 static_assert(pf == s.*&S::pf, "");
880 static_assert(pm == &S::m, "");
881 static_assert(pm != pn, "");
882 static_assert(s.pn != pn, "");
883 static_assert(s.pn == pm, "");
884 static_assert(pg != nullptr, "");
885 static_assert(pf != nullptr, "");
886 static_assert((int S::*)nullptr == nullptr, "");
887 static_assert(pg == pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}}
888 static_assert(pf != pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}}
889
Richard Smithe24f5fc2011-11-17 22:56:20 +0000890 template<int n> struct T : T<n-1> {};
891 template<> struct T<0> { int n; };
892 template<> struct T<30> : T<29> { int m; };
893
894 T<17> t17;
895 T<30> t30;
896
897 constexpr int (T<10>::*deepn) = &T<0>::n;
Richard Smith9eed49c2011-12-09 23:00:37 +0000898 static_assert(&(t17.*deepn) == &t17.n, "");
Richard Smithb02e4622012-02-01 01:42:44 +0000899 static_assert(deepn == &T<2>::n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000900
901 constexpr int (T<15>::*deepm) = (int(T<10>::*))&T<30>::m;
902 constexpr int *pbad = &(t17.*deepm); // expected-error {{constant expression}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000903 static_assert(&(t30.*deepm) == &t30.m, "");
Richard Smithb02e4622012-02-01 01:42:44 +0000904 static_assert(deepm == &T<50>::m, "");
905 static_assert(deepm != deepn, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000906
907 constexpr T<5> *p17_5 = &t17;
908 constexpr T<13> *p17_13 = (T<13>*)p17_5;
Richard Smithb4e85ed2012-01-06 16:39:00 +0000909 constexpr T<23> *p17_23 = (T<23>*)p17_13; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'T<17>' to type 'T<23>'}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000910 static_assert(&(p17_5->*(int(T<3>::*))deepn) == &t17.n, "");
911 static_assert(&(p17_13->*deepn) == &t17.n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000912 constexpr int *pbad2 = &(p17_13->*(int(T<9>::*))deepm); // expected-error {{constant expression}}
913
914 constexpr T<5> *p30_5 = &t30;
915 constexpr T<23> *p30_23 = (T<23>*)p30_5;
916 constexpr T<13> *p30_13 = p30_23;
Richard Smith9eed49c2011-12-09 23:00:37 +0000917 static_assert(&(p30_5->*(int(T<3>::*))deepn) == &t30.n, "");
918 static_assert(&(p30_13->*deepn) == &t30.n, "");
919 static_assert(&(p30_23->*deepn) == &t30.n, "");
920 static_assert(&(p30_5->*(int(T<2>::*))deepm) == &t30.m, "");
921 static_assert(&(((T<17>*)p30_13)->*deepm) == &t30.m, "");
922 static_assert(&(p30_23->*deepm) == &t30.m, "");
Richard Smithb02e4622012-02-01 01:42:44 +0000923
924 struct Base { int n; };
925 template<int N> struct Mid : Base {};
926 struct Derived : Mid<0>, Mid<1> {};
927 static_assert(&Mid<0>::n == &Mid<1>::n, "");
928 static_assert((int Derived::*)(int Mid<0>::*)&Mid<0>::n !=
929 (int Derived::*)(int Mid<1>::*)&Mid<1>::n, "");
930 static_assert(&Mid<0>::n == (int Mid<0>::*)&Base::n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000931}
932
933namespace ArrayBaseDerived {
934
935 struct Base {
936 constexpr Base() {}
937 int n = 0;
938 };
939 struct Derived : Base {
940 constexpr Derived() {}
Richard Smith84046262013-04-21 01:08:50 +0000941 constexpr const int *f() const { return &n; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000942 };
943
944 constexpr Derived a[10];
945 constexpr Derived *pd3 = const_cast<Derived*>(&a[3]);
946 constexpr Base *pb3 = const_cast<Derived*>(&a[3]);
Richard Smith9eed49c2011-12-09 23:00:37 +0000947 static_assert(pb3 == pd3, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000948
949 // pb3 does not point to an array element.
950 constexpr Base *pb4 = pb3 + 1; // ok, one-past-the-end pointer.
Richard Smithb4e85ed2012-01-06 16:39:00 +0000951 constexpr int pb4n = pb4->n; // expected-error {{constant expression}} expected-note {{cannot access field of pointer past the end}}
952 constexpr Base *err_pb5 = pb3 + 2; // expected-error {{constant expression}} expected-note {{cannot refer to element 2}} expected-note {{here}}
953 constexpr int err_pb5n = err_pb5->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb5' is not a constant expression}}
954 constexpr Base *err_pb2 = pb3 - 1; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} expected-note {{here}}
955 constexpr int err_pb2n = err_pb2->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb2'}}
Richard Smithe24f5fc2011-11-17 22:56:20 +0000956 constexpr Base *pb3a = pb4 - 1;
957
958 // pb4 does not point to a Derived.
Richard Smithb4e85ed2012-01-06 16:39:00 +0000959 constexpr Derived *err_pd4 = (Derived*)pb4; // expected-error {{constant expression}} expected-note {{cannot access derived class of pointer past the end}}
Richard Smithe24f5fc2011-11-17 22:56:20 +0000960 constexpr Derived *pd3a = (Derived*)pb3a;
961 constexpr int pd3n = pd3a->n;
962
963 // pd3a still points to the Derived array.
964 constexpr Derived *pd6 = pd3a + 3;
Richard Smith9eed49c2011-12-09 23:00:37 +0000965 static_assert(pd6 == &a[6], "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000966 constexpr Derived *pd9 = pd6 + 3;
967 constexpr Derived *pd10 = pd6 + 4;
968 constexpr int pd9n = pd9->n; // ok
Richard Smithb4e85ed2012-01-06 16:39:00 +0000969 constexpr int err_pd10n = pd10->n; // expected-error {{constant expression}} expected-note {{cannot access base class of pointer past the end}}
Richard Smithe24f5fc2011-11-17 22:56:20 +0000970 constexpr int pd0n = pd10[-10].n;
Richard Smithb4e85ed2012-01-06 16:39:00 +0000971 constexpr int err_pdminus1n = pd10[-11].n; // expected-error {{constant expression}} expected-note {{cannot refer to element -1 of}}
Richard Smithe24f5fc2011-11-17 22:56:20 +0000972
973 constexpr Base *pb9 = pd9;
974 constexpr const int *(Base::*pfb)() const =
975 static_cast<const int *(Base::*)() const>(&Derived::f);
Richard Smith9eed49c2011-12-09 23:00:37 +0000976 static_assert((pb9->*pfb)() == &a[9].n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000977}
978
Richard Smith59efe262011-11-11 04:05:33 +0000979namespace Complex {
980
981class complex {
982 int re, im;
983public:
984 constexpr complex(int re = 0, int im = 0) : re(re), im(im) {}
985 constexpr complex(const complex &o) : re(o.re), im(o.im) {}
986 constexpr complex operator-() const { return complex(-re, -im); }
987 friend constexpr complex operator+(const complex &l, const complex &r) {
988 return complex(l.re + r.re, l.im + r.im);
989 }
990 friend constexpr complex operator-(const complex &l, const complex &r) {
991 return l + -r;
992 }
993 friend constexpr complex operator*(const complex &l, const complex &r) {
994 return complex(l.re * r.re - l.im * r.im, l.re * r.im + l.im * r.re);
995 }
996 friend constexpr bool operator==(const complex &l, const complex &r) {
997 return l.re == r.re && l.im == r.im;
998 }
999 constexpr bool operator!=(const complex &r) const {
1000 return re != r.re || im != r.im;
1001 }
1002 constexpr int real() const { return re; }
1003 constexpr int imag() const { return im; }
1004};
1005
1006constexpr complex i = complex(0, 1);
1007constexpr complex k = (3 + 4*i) * (6 - 4*i);
Richard Smith9eed49c2011-12-09 23:00:37 +00001008static_assert(complex(1,0).real() == 1, "");
1009static_assert(complex(1,0).imag() == 0, "");
1010static_assert(((complex)1).imag() == 0, "");
1011static_assert(k.real() == 34, "");
1012static_assert(k.imag() == 12, "");
1013static_assert(k - 34 == 12*i, "");
1014static_assert((complex)1 == complex(1), "");
1015static_assert((complex)1 != complex(0, 1), "");
1016static_assert(complex(1) == complex(1), "");
1017static_assert(complex(1) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001018constexpr complex makeComplex(int re, int im) { return complex(re, im); }
Richard Smith9eed49c2011-12-09 23:00:37 +00001019static_assert(makeComplex(1,0) == complex(1), "");
1020static_assert(makeComplex(1,0) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001021
1022class complex_wrap : public complex {
1023public:
1024 constexpr complex_wrap(int re, int im = 0) : complex(re, im) {}
1025 constexpr complex_wrap(const complex_wrap &o) : complex(o) {}
1026};
1027
Richard Smith9eed49c2011-12-09 23:00:37 +00001028static_assert((complex_wrap)1 == complex(1), "");
1029static_assert((complex)1 != complex_wrap(0, 1), "");
1030static_assert(complex(1) == complex_wrap(1), "");
1031static_assert(complex_wrap(1) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001032constexpr complex_wrap makeComplexWrap(int re, int im) {
1033 return complex_wrap(re, im);
1034}
Richard Smith9eed49c2011-12-09 23:00:37 +00001035static_assert(makeComplexWrap(1,0) == complex(1), "");
1036static_assert(makeComplexWrap(1,0) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001037
1038}
Eli Friedmanf59ff8c2011-12-17 02:24:21 +00001039
1040namespace PR11595 {
Richard Smith84046262013-04-21 01:08:50 +00001041 struct A { constexpr bool operator==(int x) const { return true; } };
Richard Smithaf2c7a12011-12-19 22:01:37 +00001042 struct B { B(); A& x; };
1043 static_assert(B().x == 3, ""); // expected-error {{constant expression}} expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
1044
Richard Smith745f5142012-01-27 01:14:48 +00001045 constexpr bool f(int k) { // expected-error {{constexpr function never produces a constant expression}}
Richard Smithaf2c7a12011-12-19 22:01:37 +00001046 return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
1047 }
Eli Friedmanf59ff8c2011-12-17 02:24:21 +00001048}
Richard Smithbc6abe92011-12-19 22:12:41 +00001049
1050namespace ExprWithCleanups {
1051 struct A { A(); ~A(); int get(); };
1052 constexpr int get(bool FromA) { return FromA ? A().get() : 1; }
1053 constexpr int n = get(false);
1054}
Richard Smith7098cbd2011-12-21 05:04:46 +00001055
1056namespace Volatile {
1057
1058volatile constexpr int n1 = 0; // expected-note {{here}}
1059volatile const int n2 = 0; // expected-note {{here}}
1060int n3 = 37; // expected-note {{declared here}}
1061
Richard Smith9ec71972012-02-05 01:23:16 +00001062constexpr int m1 = n1; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
1063constexpr int m2 = n2; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
1064constexpr int m1b = const_cast<const int&>(n1); // expected-error {{constant expression}} expected-note {{read of volatile object 'n1'}}
1065constexpr int m2b = const_cast<const int&>(n2); // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}}
Richard Smith7098cbd2011-12-21 05:04:46 +00001066
1067struct T { int n; };
1068const T t = { 42 }; // expected-note {{declared here}}
1069
1070constexpr int f(volatile int &&r) {
Richard Smith9ec71972012-02-05 01:23:16 +00001071 return r; // expected-note {{read of volatile-qualified type 'volatile int'}}
1072}
1073constexpr int g(volatile int &&r) {
1074 return const_cast<int&>(r); // expected-note {{read of volatile temporary is not allowed in a constant expression}}
Richard Smith7098cbd2011-12-21 05:04:46 +00001075}
1076struct S {
Richard Smith9ec71972012-02-05 01:23:16 +00001077 int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}}
1078 int k : g(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'g(0)'}}
Richard Smith7098cbd2011-12-21 05:04:46 +00001079 int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}}
1080 int m : t.n; // expected-error {{constant expression}} expected-note {{read of non-constexpr variable}}
1081};
1082
1083}
Richard Smithdd4b3502011-12-25 21:17:58 +00001084
1085namespace ExternConstexpr {
1086 extern constexpr int n = 0;
1087 extern constexpr int m; // expected-error {{constexpr variable declaration must be a definition}}
1088 void f() {
1089 extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}}
1090 constexpr int j = 0;
1091 constexpr int k; // expected-error {{default initialization of an object of const type}}
1092 }
1093}
Eli Friedman7ead5c72012-01-10 04:58:17 +00001094
1095namespace ComplexConstexpr {
1096 constexpr _Complex float test1 = {};
1097 constexpr _Complex float test2 = {1};
1098 constexpr _Complex double test3 = {1,2};
1099 constexpr _Complex int test4 = {4};
1100 constexpr _Complex int test5 = 4;
1101 constexpr _Complex int test6 = {5,6};
Eli Friedmanf6c17a42012-01-13 23:34:56 +00001102 typedef _Complex float fcomplex;
1103 constexpr fcomplex test7 = fcomplex();
Richard Smith86024012012-02-18 22:04:06 +00001104
1105 constexpr const double &t2r = __real test3;
1106 constexpr const double &t2i = __imag test3;
1107 static_assert(&t2r + 1 == &t2i, "");
1108 static_assert(t2r == 1.0, "");
1109 static_assert(t2i == 2.0, "");
1110 constexpr const double *t2p = &t2r;
1111 static_assert(t2p[-1] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element -1 of array of 2 elements}}
1112 static_assert(t2p[0] == 1.0, "");
1113 static_assert(t2p[1] == 2.0, "");
1114 static_assert(t2p[2] == 0.0, ""); // expected-error {{constant expr}} expected-note {{one-past-the-end pointer}}
1115 static_assert(t2p[3] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element 3 of array of 2 elements}}
1116 constexpr _Complex float *p = 0;
1117 constexpr float pr = __real *p; // expected-error {{constant expr}} expected-note {{cannot access real component of null}}
1118 constexpr float pi = __imag *p; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of null}}
1119 constexpr const _Complex double *q = &test3 + 1;
1120 constexpr double qr = __real *q; // expected-error {{constant expr}} expected-note {{cannot access real component of pointer past the end}}
1121 constexpr double qi = __imag *q; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of pointer past the end}}
1122
1123 static_assert(__real test6 == 5, "");
1124 static_assert(__imag test6 == 6, "");
1125 static_assert(&__imag test6 == &__real test6 + 1, "");
Eli Friedman7ead5c72012-01-10 04:58:17 +00001126}
Eli Friedman6b3014b2012-01-18 02:54:10 +00001127
1128namespace InstantiateCaseStmt {
1129 template<int x> constexpr int f() { return x; }
1130 template<int x> int g(int c) { switch(c) { case f<x>(): return 1; } return 0; }
1131 int gg(int c) { return g<4>(c); }
1132}
Richard Smith495f42a2012-01-24 05:40:50 +00001133
1134namespace ConvertedConstantExpr {
1135 extern int &m;
1136 extern int &n;
1137
1138 constexpr int k = 4;
1139 int &m = const_cast<int&>(k);
1140
1141 // If we have nothing more interesting to say, ensure we don't produce a
1142 // useless note and instead just point to the non-constant subexpression.
1143 enum class E {
1144 em = m,
1145 en = n, // expected-error {{not a constant expression}}
1146 eo = (m +
1147 n // expected-error {{not a constant expression}}
1148 ),
1149 eq = reinterpret_cast<int>((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}}
1150 };
1151}
Richard Smithd9b02e72012-01-25 22:15:11 +00001152
1153namespace IndirectField {
1154 struct S {
1155 struct { // expected-warning {{GNU extension}}
Richard Smithf2705192013-01-31 03:11:12 +00001156 union { // expected-warning {{declared in an anonymous struct}}
1157 struct { // expected-warning {{GNU extension}} expected-warning {{declared in an anonymous union}}
Richard Smithd9b02e72012-01-25 22:15:11 +00001158 int a;
1159 int b;
1160 };
1161 int c;
1162 };
1163 int d;
1164 };
1165 union {
1166 int e;
1167 int f;
1168 };
1169 constexpr S(int a, int b, int d, int e) : a(a), b(b), d(d), e(e) {}
1170 constexpr S(int c, int d, int f) : c(c), d(d), f(f) {}
1171 };
1172
1173 constexpr S s1(1, 2, 3, 4);
1174 constexpr S s2(5, 6, 7);
1175
1176 // FIXME: The diagnostics here do a very poor job of explaining which unnamed
1177 // member is active and which is requested.
1178 static_assert(s1.a == 1, "");
1179 static_assert(s1.b == 2, "");
1180 static_assert(s1.c == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1181 static_assert(s1.d == 3, "");
1182 static_assert(s1.e == 4, "");
1183 static_assert(s1.f == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1184
1185 static_assert(s2.a == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1186 static_assert(s2.b == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1187 static_assert(s2.c == 5, "");
1188 static_assert(s2.d == 6, "");
1189 static_assert(s2.e == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1190 static_assert(s2.f == 7, "");
1191}
Richard Smithf15fda02012-02-02 01:16:57 +00001192
Richard Smithb4e5e282012-02-09 03:29:58 +00001193// DR1405: don't allow reading mutable members in constant expressions.
1194namespace MutableMembers {
1195 struct MM {
1196 mutable int n; // expected-note 3{{declared here}}
1197 } constexpr mm = { 4 };
1198 constexpr int mmn = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
1199 int x = (mm.n = 1, 3);
1200 constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
1201
1202 // Here's one reason why allowing this would be a disaster...
1203 template<int n> struct Id { int k = n; };
1204 int f() {
1205 constexpr MM m = { 0 };
1206 ++m.n;
1207 return Id<m.n>().k; // expected-error {{not a constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
1208 }
1209
1210 struct A { int n; };
1211 struct B { mutable A a; }; // expected-note {{here}}
1212 struct C { B b; };
1213 constexpr C c[3] = {};
1214 constexpr int k = c[1].b.a.n; // expected-error {{constant expression}} expected-note {{mutable}}
1215}
1216
Richard Smithf15fda02012-02-02 01:16:57 +00001217namespace Fold {
1218
1219 // This macro forces its argument to be constant-folded, even if it's not
1220 // otherwise a constant expression.
1221 #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
1222
1223 constexpr int n = (int)(char*)123; // expected-error {{constant expression}} expected-note {{reinterpret_cast}}
1224 constexpr int m = fold((int)(char*)123); // ok
1225 static_assert(m == 123, "");
1226
1227 #undef fold
1228
1229}
Richard Smith83587db2012-02-15 02:18:13 +00001230
1231namespace DR1454 {
1232
1233constexpr const int &f(const int &n) { return n; }
1234constexpr int k1 = f(0); // ok
1235
1236struct Wrap {
1237 const int &value;
1238};
1239constexpr const Wrap &g(const Wrap &w) { return w; }
1240constexpr int k2 = g({0}).value; // ok
1241
1242constexpr const int &i = 0; // expected-error {{constant expression}} expected-note {{temporary}} expected-note 2{{here}}
1243constexpr const int j = i; // expected-error {{constant expression}} expected-note {{initializer of 'i' is not a constant expression}}
1244
1245}
Richard Smith74e1ad92012-02-16 02:46:34 +00001246
1247namespace RecursiveOpaqueExpr {
1248 template<typename Iter>
1249 constexpr auto LastNonzero(Iter p, Iter q) -> decltype(+*p) {
1250 return p != q ? (LastNonzero(p+1, q) ?: *p) : 0; // expected-warning {{GNU}}
1251 }
1252
1253 constexpr int arr1[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 0 };
1254 static_assert(LastNonzero(begin(arr1), end(arr1)) == 4, "");
1255
1256 constexpr int arr2[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 5 };
1257 static_assert(LastNonzero(begin(arr2), end(arr2)) == 5, "");
Richard Smithe92b1f42012-06-26 08:12:11 +00001258
1259 constexpr int arr3[] = {
1260 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
1261 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
1262 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
1263 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
1264 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
1265 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
1266 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
1267 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1268 static_assert(LastNonzero(begin(arr3), end(arr3)) == 2, "");
Richard Smith74e1ad92012-02-16 02:46:34 +00001269}
1270
1271namespace VLASizeof {
1272
1273 void f(int k) {
1274 int arr[k]; // expected-warning {{C99}}
1275 constexpr int n = 1 +
1276 sizeof(arr) // expected-error {{constant expression}}
1277 * 3;
1278 }
1279}
Richard Smithb78ae972012-02-18 04:58:18 +00001280
1281namespace CompoundLiteral {
1282 // FIXME:
1283 // We don't model the semantics of this correctly: the compound literal is
1284 // represented as a prvalue in the AST, but actually behaves like an lvalue.
1285 // We treat the compound literal as a temporary and refuse to produce a
1286 // pointer to it. This is OK: we're not required to treat this as a constant
1287 // in C++, and in C we model compound literals as lvalues.
1288 constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}}
1289}
Richard Smith4b1f6842012-03-13 20:58:32 +00001290
1291namespace Vector {
1292 typedef int __attribute__((vector_size(16))) VI4;
1293 constexpr VI4 f(int n) {
1294 return VI4 { n * 3, n + 4, n - 5, n / 6 };
1295 }
1296 constexpr auto v1 = f(10);
1297
1298 typedef double __attribute__((vector_size(32))) VD4;
1299 constexpr VD4 g(int n) {
1300 return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 }; // expected-warning {{C99}}
1301 }
1302 constexpr auto v2 = g(4);
1303}
John McCall8d59dee2012-05-01 00:38:49 +00001304
1305// PR12626, redux
1306namespace InvalidClasses {
1307 void test0() {
1308 struct X; // expected-note {{forward declaration}}
1309 struct Y { bool b; X x; }; // expected-error {{field has incomplete type}}
1310 Y y;
1311 auto& b = y.b;
1312 }
1313}
Richard Smithdbbeccc2012-05-15 05:04:02 +00001314
Richard Smitha10b9782013-04-22 15:31:51 +00001315namespace NamespaceAlias {
1316 constexpr int f() {
1317 namespace NS = NamespaceAlias; // expected-warning {{use of this statement in a constexpr function is a C++1y extension}}
1318 return &NS::f != nullptr;
1319 }
1320}
1321
Richard Smith622da852012-07-02 06:15:40 +00001322// Constructors can be implicitly constexpr, even for a non-literal type.
1323namespace ImplicitConstexpr {
1324 struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}}
Richard Smith604fb382012-08-07 22:06:48 +00001325 struct R { constexpr R() noexcept; constexpr R(const R&) noexcept; constexpr R(R&&) noexcept; ~R() noexcept; };
Richard Smith622da852012-07-02 06:15:40 +00001326 struct S { R r; }; // expected-note 3{{here}}
Richard Smith604fb382012-08-07 22:06:48 +00001327 struct T { T(const T&) noexcept; T(T &&) noexcept; ~T() noexcept; };
Richard Smith622da852012-07-02 06:15:40 +00001328 struct U { T t; }; // expected-note 3{{here}}
1329 static_assert(!__is_literal_type(Q), "");
1330 static_assert(!__is_literal_type(R), "");
1331 static_assert(!__is_literal_type(S), "");
1332 static_assert(!__is_literal_type(T), "");
1333 static_assert(!__is_literal_type(U), "");
1334 struct Test {
1335 friend Q::Q() noexcept; // expected-error {{follows constexpr}}
1336 friend Q::Q(Q&&) noexcept; // expected-error {{follows constexpr}}
1337 friend Q::Q(const Q&) noexcept; // expected-error {{follows constexpr}}
1338 friend S::S() noexcept; // expected-error {{follows constexpr}}
1339 friend S::S(S&&) noexcept; // expected-error {{follows constexpr}}
1340 friend S::S(const S&) noexcept; // expected-error {{follows constexpr}}
1341 friend constexpr U::U() noexcept; // expected-error {{follows non-constexpr}}
1342 friend constexpr U::U(U&&) noexcept; // expected-error {{follows non-constexpr}}
1343 friend constexpr U::U(const U&) noexcept; // expected-error {{follows non-constexpr}}
1344 };
1345}
1346
Richard Smithdbbeccc2012-05-15 05:04:02 +00001347// Indirectly test that an implicit lvalue to xvalue conversion performed for
1348// an NRVO move operation isn't implemented as CK_LValueToRValue.
1349namespace PR12826 {
1350 struct Foo {};
1351 constexpr Foo id(Foo x) { return x; }
1352 constexpr Foo res(id(Foo()));
1353}
Richard Smithf4bb8d02012-07-05 08:39:21 +00001354
1355namespace PR13273 {
1356 struct U {
1357 int t;
1358 U() = default;
1359 };
1360
1361 struct S : U {
1362 S() = default;
1363 };
1364
1365 // S's default constructor isn't constexpr, because U's default constructor
1366 // doesn't initialize 't', but it's trivial, so value-initialization doesn't
1367 // actually call it.
1368 static_assert(S{}.t == 0, "");
1369}
Richard Smith20599392012-07-07 08:35:56 +00001370
1371namespace PR12670 {
1372 struct S {
1373 constexpr S(int a0) : m(a0) {}
1374 constexpr S() : m(6) {}
1375 int m;
1376 };
1377 constexpr S x[3] = { {4}, 5 };
1378 static_assert(x[0].m == 4, "");
1379 static_assert(x[1].m == 5, "");
1380 static_assert(x[2].m == 6, "");
1381}
Richard Smith604fb382012-08-07 22:06:48 +00001382
1383// Indirectly test that an implicit lvalue-to-rvalue conversion is performed
1384// when a conditional operator has one argument of type void and where the other
1385// is a glvalue of class type.
1386namespace ConditionalLValToRVal {
1387 struct A {
1388 constexpr A(int a) : v(a) {}
1389 int v;
1390 };
1391
1392 constexpr A f(const A &a) {
1393 return a.v == 0 ? throw a : a;
1394 }
1395
1396 constexpr A a(4);
1397 static_assert(f(a).v == 4, "");
1398}
Hans Wennborg29f431b2012-08-29 09:17:34 +00001399
1400namespace TLS {
1401 __thread int n;
Hans Wennborg48def652012-08-29 18:27:29 +00001402 int m;
1403
1404 constexpr bool b = &n == &n;
1405
1406 constexpr int *p = &n; // expected-error{{constexpr variable 'p' must be initialized by a constant expression}}
1407
1408 constexpr int *f() { return &n; }
1409 constexpr int *q = f(); // expected-error{{constexpr variable 'q' must be initialized by a constant expression}}
1410 constexpr bool c = f() == f();
1411
1412 constexpr int *g() { return &m; }
1413 constexpr int *r = g();
Hans Wennborg29f431b2012-08-29 09:17:34 +00001414}
Richard Smith01cad022012-10-01 20:36:17 +00001415
1416namespace Void {
1417 constexpr void f() { return; } // expected-error{{constexpr function's return type 'void' is not a literal type}}
1418
1419 void assert_failed(const char *msg, const char *file, int line); // expected-note {{declared here}}
1420#define ASSERT(expr) ((expr) ? static_cast<void>(0) : assert_failed(#expr, __FILE__, __LINE__))
1421 template<typename T, size_t S>
1422 constexpr T get(T (&a)[S], size_t k) {
1423 return ASSERT(k > 0 && k < S), a[k]; // expected-note{{non-constexpr function 'assert_failed'}}
1424 }
1425#undef ASSERT
1426 template int get(int (&a)[4], size_t);
1427 constexpr int arr[] = { 4, 1, 2, 3, 4 };
1428 static_assert(get(arr, 1) == 1, "");
1429 static_assert(get(arr, 4) == 4, "");
1430 static_assert(get(arr, 0) == 4, ""); // expected-error{{not an integral constant expression}} \
1431 // expected-note{{in call to 'get(arr, 0)'}}
1432}
Richard Smith9be36ab2012-10-17 23:52:07 +00001433
1434namespace std { struct type_info; }
1435
1436namespace TypeId {
1437 struct A { virtual ~A(); };
1438 A f();
1439 A &g();
1440 constexpr auto &x = typeid(f());
1441 constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \
1442 // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}}
1443}
Richard Smith9568f0c2012-10-29 18:26:47 +00001444
1445namespace PR14203 {
1446 struct duration {
1447 constexpr duration() {}
1448 constexpr operator int() const { return 0; }
1449 };
1450 template<typename T> void f() {
1451 // If we want to evaluate this at the point of the template definition, we
1452 // need to trigger the implicit definition of the move constructor at that
1453 // point.
1454 // FIXME: C++ does not permit us to implicitly define it at the appropriate
1455 // times, since it is only allowed to be implicitly defined when it is
1456 // odr-used.
1457 constexpr duration d = duration();
1458 }
1459 // FIXME: It's unclear whether this is valid. On the one hand, we're not
1460 // allowed to generate a move constructor. On the other hand, if we did,
Richard Smithce2661f2012-11-07 01:14:25 +00001461 // this would be a constant expression. For now, we generate a move
1462 // constructor here.
1463 int n = sizeof(short{duration(duration())});
Richard Smith9568f0c2012-10-29 18:26:47 +00001464}
Richard Smith99ad3592013-04-22 14:44:29 +00001465
1466namespace ArrayEltInit {
1467 struct A {
1468 constexpr A() : p(&p) {}
1469 void *p;
1470 };
1471 constexpr A a[10];
1472 static_assert(a[0].p == &a[0].p, "");
1473 static_assert(a[9].p == &a[9].p, "");
1474 static_assert(a[0].p != &a[9].p, "");
1475 static_assert(a[9].p != &a[0].p, "");
1476
1477 constexpr A b[10] = {};
1478 static_assert(b[0].p == &b[0].p, "");
1479 static_assert(b[9].p == &b[9].p, "");
1480 static_assert(b[0].p != &b[9].p, "");
1481 static_assert(b[9].p != &b[0].p, "");
1482}