blob: 09a9cb5dd8dbe6333076009f444abfc02f6fbd57 [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 Smithbebf5b12013-04-26 14:36:30 +0000307 expected-note {{cast that 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 Smithbebf5b12013-04-26 14:36:30 +0000310 expected-note {{cast that 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 Smithbebf5b12013-04-26 14:36:30 +0000313 expected-note {{cast that 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 Smithbebf5b12013-04-26 14:36:30 +0000316 expected-note {{cast that 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}}
Richard Smithbebf5b12013-04-26 14:36:30 +0000365constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast that 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 Smith30ae1ed2013-05-05 16:40:13 +0000417namespace Parens {
418 constexpr unsigned char a[] = ("foo"), b[] = {"foo"}, c[] = {("foo")},
419 d[4] = ("foo"), e[5] = {"foo"}, f[6] = {("foo")};
420 static_assert(a[0] == 'f', "");
421 static_assert(b[1] == 'o', "");
422 static_assert(c[2] == 'o', "");
423 static_assert(d[0] == 'f', "");
424 static_assert(e[1] == 'o', "");
425 static_assert(f[2] == 'o', "");
426 static_assert(f[5] == 0, "");
427 static_assert(f[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
428}
429
Richard Smith59efe262011-11-11 04:05:33 +0000430}
431
432namespace Array {
433
Richard Smith1d238ea2011-12-21 02:55:12 +0000434template<typename Iter>
435constexpr auto Sum(Iter begin, Iter end) -> decltype(+*begin) {
Richard Smith59efe262011-11-11 04:05:33 +0000436 return begin == end ? 0 : *begin + Sum(begin+1, end);
437}
Richard Smith59efe262011-11-11 04:05:33 +0000438
439constexpr int xs[] = { 1, 2, 3, 4, 5 };
440constexpr int ys[] = { 5, 4, 3, 2, 1 };
441constexpr int sum_xs = Sum(begin(xs), end(xs));
Richard Smith9eed49c2011-12-09 23:00:37 +0000442static_assert(sum_xs == 15, "");
Richard Smith59efe262011-11-11 04:05:33 +0000443
444constexpr int ZipFoldR(int (*F)(int x, int y, int c), int n,
445 const int *xs, const int *ys, int c) {
Richard Smithdaaefc52011-12-14 23:32:26 +0000446 return n ? F(
Richard Smith7098cbd2011-12-21 05:04:46 +0000447 *xs, // expected-note {{read of dereferenced one-past-the-end pointer}}
Richard Smith08d6e032011-12-16 19:06:07 +0000448 *ys,
449 ZipFoldR(F, n-1, xs+1, ys+1, c)) // \
450 expected-note {{in call to 'ZipFoldR(&SubMul, 2, &xs[4], &ys[4], 1)'}} \
451 expected-note {{in call to 'ZipFoldR(&SubMul, 1, &xs[5], &ys[5], 1)'}}
452 : c;
Richard Smith59efe262011-11-11 04:05:33 +0000453}
454constexpr int MulAdd(int x, int y, int c) { return x * y + c; }
455constexpr int InnerProduct = ZipFoldR(MulAdd, 5, xs, ys, 0);
Richard Smith9eed49c2011-12-09 23:00:37 +0000456static_assert(InnerProduct == 35, "");
Richard Smith59efe262011-11-11 04:05:33 +0000457
458constexpr int SubMul(int x, int y, int c) { return (x - y) * c; }
459constexpr int DiffProd = ZipFoldR(SubMul, 2, xs+3, ys+3, 1);
Richard Smith9eed49c2011-12-09 23:00:37 +0000460static_assert(DiffProd == 8, "");
Richard Smith08d6e032011-12-16 19:06:07 +0000461static_assert(ZipFoldR(SubMul, 3, xs+3, ys+3, 1), ""); // \
462 expected-error {{constant expression}} \
463 expected-note {{in call to 'ZipFoldR(&SubMul, 3, &xs[3], &ys[3], 1)'}}
Richard Smith59efe262011-11-11 04:05:33 +0000464
465constexpr const int *p = xs + 3;
466constexpr int xs4 = p[1]; // ok
Richard Smith7098cbd2011-12-21 05:04:46 +0000467constexpr 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 +0000468constexpr int xs6 = p[3]; // expected-error {{constant expression}} expected-note {{cannot refer to element 6}}
Richard Smith59efe262011-11-11 04:05:33 +0000469constexpr int xs0 = p[-3]; // ok
Richard Smithb4e85ed2012-01-06 16:39:00 +0000470constexpr int xs_1 = p[-4]; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
Richard Smith59efe262011-11-11 04:05:33 +0000471
472constexpr 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 +0000473static_assert(zs[0][0][0][0] == 1, "");
474static_assert(zs[1][1][1][1] == 16, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000475static_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 +0000476static_assert((&zs[0][0][0][2])[-1] == 2, "");
477static_assert(**(**(zs + 1) + 1) == 11, "");
Richard Smithb4e85ed2012-01-06 16:39:00 +0000478static_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}}
479static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2) == 11, "");
480constexpr 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 +0000481
Richard Smith08d6e032011-12-16 19:06:07 +0000482constexpr int fail(const int &p) {
Richard Smithb4e85ed2012-01-06 16:39:00 +0000483 return (&p)[64]; // expected-note {{cannot refer to element 64 of array of 2 elements}}
Richard Smith08d6e032011-12-16 19:06:07 +0000484}
Richard Smithb4e85ed2012-01-06 16:39:00 +0000485static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2)) == 11, ""); // \
Richard Smith08d6e032011-12-16 19:06:07 +0000486expected-error {{static_assert expression is not an integral constant expression}} \
487expected-note {{in call to 'fail(zs[1][0][1][0])'}}
488
Richard Smithd7c56e12011-12-29 21:57:33 +0000489constexpr int arr[40] = { 1, 2, 3, [8] = 4 }; // expected-warning {{C99 feature}}
Richard Smith59efe262011-11-11 04:05:33 +0000490constexpr int SumNonzero(const int *p) {
491 return *p + (*p ? SumNonzero(p+1) : 0);
492}
493constexpr int CountZero(const int *p, const int *q) {
494 return p == q ? 0 : (*p == 0) + CountZero(p+1, q);
495}
Richard Smith9eed49c2011-12-09 23:00:37 +0000496static_assert(SumNonzero(arr) == 6, "");
497static_assert(CountZero(arr, arr + 40) == 36, "");
Richard Smith59efe262011-11-11 04:05:33 +0000498
Richard Smithe24f5fc2011-11-17 22:56:20 +0000499struct ArrayElem {
500 constexpr ArrayElem() : n(0) {}
501 int n;
Richard Smith84046262013-04-21 01:08:50 +0000502 constexpr int f() const { return n; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000503};
504struct ArrayRVal {
505 constexpr ArrayRVal() {}
506 ArrayElem elems[10];
507};
Richard Smith9eed49c2011-12-09 23:00:37 +0000508static_assert(ArrayRVal().elems[3].f() == 0, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000509
Richard Smithde31aa72012-07-07 22:48:24 +0000510constexpr int selfref[2][2][2] = {
511 selfref[1][1][1] + 1, selfref[0][0][0] + 1,
512 selfref[1][0][1] + 1, selfref[0][1][0] + 1,
513 selfref[1][0][0] + 1, selfref[0][1][1] + 1 };
514static_assert(selfref[0][0][0] == 1, "");
515static_assert(selfref[0][0][1] == 2, "");
516static_assert(selfref[0][1][0] == 1, "");
517static_assert(selfref[0][1][1] == 2, "");
518static_assert(selfref[1][0][0] == 1, "");
519static_assert(selfref[1][0][1] == 3, "");
520static_assert(selfref[1][1][0] == 0, "");
521static_assert(selfref[1][1][1] == 0, "");
522
Richard Smitha4334df2012-07-10 22:12:55 +0000523struct TrivialDefCtor { int n; };
524typedef TrivialDefCtor TDCArray[2][2];
525static_assert(TDCArray{}[1][1].n == 0, "");
526
527struct NonAggregateTDC : TrivialDefCtor {};
528typedef NonAggregateTDC NATDCArray[2][2];
529static_assert(NATDCArray{}[1][1].n == 0, "");
530
Richard Smith59efe262011-11-11 04:05:33 +0000531}
532
533namespace DependentValues {
534
535struct I { int n; typedef I V[10]; };
536I::V x, y;
Richard Smith9568f0c2012-10-29 18:26:47 +0000537int g();
Richard Smith1432a432012-10-28 06:18:02 +0000538template<bool B, typename T> struct S : T {
Richard Smith59efe262011-11-11 04:05:33 +0000539 int k;
540 void f() {
541 I::V &cells = B ? x : y;
542 I &i = cells[k];
543 switch (i.n) {}
Richard Smith1432a432012-10-28 06:18:02 +0000544
Richard Smith9568f0c2012-10-29 18:26:47 +0000545 // FIXME: We should be able to diagnose this.
546 constexpr int n = g();
Richard Smith1432a432012-10-28 06:18:02 +0000547
548 constexpr int m = this->g(); // ok, could be constexpr
Richard Smith59efe262011-11-11 04:05:33 +0000549 }
550};
551
552}
553
554namespace Class {
555
556struct A { constexpr A(int a, int b) : k(a + b) {} int k; };
557constexpr int fn(const A &a) { return a.k; }
Richard Smith9eed49c2011-12-09 23:00:37 +0000558static_assert(fn(A(4,5)) == 9, "");
Richard Smith59efe262011-11-11 04:05:33 +0000559
560struct B { int n; int m; } constexpr b = { 0, b.n }; // expected-warning {{uninitialized}}
561struct C {
562 constexpr C(C *this_) : m(42), n(this_->m) {} // ok
563 int m, n;
564};
565struct D {
566 C c;
567 constexpr D() : c(&c) {}
568};
Richard Smith9eed49c2011-12-09 23:00:37 +0000569static_assert(D().c.n == 42, "");
Richard Smith59efe262011-11-11 04:05:33 +0000570
Richard Smith61802452011-12-22 02:22:31 +0000571struct E {
Richard Smith83587db2012-02-15 02:18:13 +0000572 constexpr E() : p(&p) {}
Richard Smith59efe262011-11-11 04:05:33 +0000573 void *p;
574};
Richard Smith83587db2012-02-15 02:18:13 +0000575constexpr 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 +0000576// This is a constant expression if we elide the copy constructor call, and
577// is not a constant expression if we don't! But we do, so it is.
Richard Smith61802452011-12-22 02:22:31 +0000578constexpr E e2 = E();
579static_assert(e2.p == &e2.p, "");
Richard Smith099e7f62011-12-19 06:19:21 +0000580constexpr E e3;
Richard Smith9eed49c2011-12-09 23:00:37 +0000581static_assert(e3.p == &e3.p, "");
Richard Smith59efe262011-11-11 04:05:33 +0000582
583extern const class F f;
584struct F {
585 constexpr F() : p(&f.p) {}
586 const void *p;
587};
Richard Smith099e7f62011-12-19 06:19:21 +0000588constexpr F f;
Richard Smith59efe262011-11-11 04:05:33 +0000589
590struct G {
591 struct T {
592 constexpr T(T *p) : u1(), u2(p) {}
593 union U1 {
594 constexpr U1() {}
595 int a, b = 42;
596 } u1;
597 union U2 {
598 constexpr U2(T *p) : c(p->u1.b) {}
599 int c, d;
600 } u2;
601 } t;
602 constexpr G() : t(&t) {}
603} constexpr g;
604
Richard Smith7098cbd2011-12-21 05:04:46 +0000605static_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 +0000606static_assert(g.t.u1.b == 42, "");
607static_assert(g.t.u2.c == 42, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000608static_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 +0000609
610struct S {
611 int a, b;
612 const S *p;
613 double d;
614 const char *q;
615
616 constexpr S(int n, const S *p) : a(5), b(n), p(p), d(n), q("hello") {}
617};
618
619S global(43, &global);
620
Richard Smith9eed49c2011-12-09 23:00:37 +0000621static_assert(S(15, &global).b == 15, "");
Richard Smith59efe262011-11-11 04:05:33 +0000622
623constexpr bool CheckS(const S &s) {
624 return s.a == 5 && s.b == 27 && s.p == &global && s.d == 27. && s.q[3] == 'l';
625}
Richard Smith9eed49c2011-12-09 23:00:37 +0000626static_assert(CheckS(S(27, &global)), "");
Richard Smith59efe262011-11-11 04:05:33 +0000627
628struct Arr {
629 char arr[3];
630 constexpr Arr() : arr{'x', 'y', 'z'} {}
631};
632constexpr int hash(Arr &&a) {
633 return a.arr[0] + a.arr[1] * 0x100 + a.arr[2] * 0x10000;
634}
635constexpr int k = hash(Arr());
Richard Smith9eed49c2011-12-09 23:00:37 +0000636static_assert(k == 0x007a7978, "");
Richard Smith59efe262011-11-11 04:05:33 +0000637
638
639struct AggregateInit {
640 const char &c;
641 int n;
642 double d;
643 int arr[5];
644 void *p;
645};
646
647constexpr AggregateInit agg1 = { "hello"[0] };
648
Richard Smith9eed49c2011-12-09 23:00:37 +0000649static_assert(strcmp_ce(&agg1.c, "hello") == 0, "");
650static_assert(agg1.n == 0, "");
651static_assert(agg1.d == 0.0, "");
Richard Smithb4e85ed2012-01-06 16:39:00 +0000652static_assert(agg1.arr[-1] == 0, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000653static_assert(agg1.arr[0] == 0, "");
654static_assert(agg1.arr[4] == 0, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000655static_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 +0000656static_assert(agg1.p == nullptr, "");
Richard Smith59efe262011-11-11 04:05:33 +0000657
Richard Smithfe587202012-04-15 02:50:59 +0000658static constexpr const unsigned char uc[] = { "foo" };
659static_assert(uc[0] == 'f', "");
660static_assert(uc[3] == 0, "");
661
Richard Smith59efe262011-11-11 04:05:33 +0000662namespace SimpleDerivedClass {
663
664struct B {
665 constexpr B(int n) : a(n) {}
666 int a;
667};
668struct D : B {
669 constexpr D(int n) : B(n) {}
670};
671constexpr D d(3);
Richard Smith9eed49c2011-12-09 23:00:37 +0000672static_assert(d.a == 3, "");
Richard Smith59efe262011-11-11 04:05:33 +0000673
674}
675
Richard Smithe24f5fc2011-11-17 22:56:20 +0000676struct Bottom { constexpr Bottom() {} };
677struct Base : Bottom {
Richard Smith59efe262011-11-11 04:05:33 +0000678 constexpr Base(int a = 42, const char *b = "test") : a(a), b(b) {}
679 int a;
680 const char *b;
681};
Richard Smithe24f5fc2011-11-17 22:56:20 +0000682struct Base2 : Bottom {
Richard Smith59efe262011-11-11 04:05:33 +0000683 constexpr Base2(const int &r) : r(r) {}
684 int q = 123;
Richard Smith099e7f62011-12-19 06:19:21 +0000685 const int &r;
Richard Smith59efe262011-11-11 04:05:33 +0000686};
687struct Derived : Base, Base2 {
688 constexpr Derived() : Base(76), Base2(a) {}
689 int c = r + b[1];
690};
691
692constexpr bool operator==(const Base &a, const Base &b) {
693 return a.a == b.a && strcmp_ce(a.b, b.b) == 0;
694}
695
696constexpr Base base;
697constexpr Base base2(76);
698constexpr Derived derived;
Richard Smith9eed49c2011-12-09 23:00:37 +0000699static_assert(derived.a == 76, "");
700static_assert(derived.b[2] == 's', "");
701static_assert(derived.c == 76 + 'e', "");
702static_assert(derived.q == 123, "");
703static_assert(derived.r == 76, "");
Richard Smith099e7f62011-12-19 06:19:21 +0000704static_assert(&derived.r == &derived.a, "");
Richard Smith59efe262011-11-11 04:05:33 +0000705
Richard Smith9eed49c2011-12-09 23:00:37 +0000706static_assert(!(derived == base), "");
707static_assert(derived == base2, "");
Richard Smith59efe262011-11-11 04:05:33 +0000708
Richard Smithe24f5fc2011-11-17 22:56:20 +0000709constexpr Bottom &bot1 = (Base&)derived;
710constexpr Bottom &bot2 = (Base2&)derived;
Richard Smith9eed49c2011-12-09 23:00:37 +0000711static_assert(&bot1 != &bot2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000712
713constexpr Bottom *pb1 = (Base*)&derived;
714constexpr Bottom *pb2 = (Base2*)&derived;
Richard Smithf15fda02012-02-02 01:16:57 +0000715static_assert(&pb1 != &pb2, "");
Richard Smith9eed49c2011-12-09 23:00:37 +0000716static_assert(pb1 == &bot1, "");
717static_assert(pb2 == &bot2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000718
Richard Smithb4e85ed2012-01-06 16:39:00 +0000719constexpr Base2 &fail = (Base2&)bot1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}}
720constexpr 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 +0000721constexpr Base2 &ok2 = (Base2&)bot2;
Richard Smith9eed49c2011-12-09 23:00:37 +0000722static_assert(&ok2 == &derived, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000723
Richard Smithb4e85ed2012-01-06 16:39:00 +0000724constexpr Base2 *pfail = (Base2*)pb1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}}
725constexpr 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 +0000726constexpr Base2 *pok2 = (Base2*)pb2;
Richard Smith9eed49c2011-12-09 23:00:37 +0000727static_assert(pok2 == &derived, "");
728static_assert(&ok2 == pok2, "");
729static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");
730static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000731
David Blaikie50800fc2012-08-08 17:33:31 +0000732constexpr 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 +0000733static_assert((Bottom*)nullB == 0, "");
734static_assert((Derived*)nullB == 0, "");
735static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");
David Blaikie50800fc2012-08-08 17:33:31 +0000736Base * nullB2 = '\0'; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *'}}
737Base * nullB3 = (0);
738// We suppress the warning in unevaluated contexts to workaround some gtest
739// behavior. Once this becomes an error this isn't a problem anymore.
740static_assert(nullB == (1 - 1), "");
741
Richard Smithe24f5fc2011-11-17 22:56:20 +0000742
Richard Smith7d580a42012-01-17 21:17:26 +0000743namespace ConversionOperators {
744
745struct T {
746 constexpr T(int n) : k(5*n - 3) {}
Richard Smith84046262013-04-21 01:08:50 +0000747 constexpr operator int() const { return k; }
Richard Smith7d580a42012-01-17 21:17:26 +0000748 int k;
749};
750
751struct S {
752 constexpr S(int n) : k(2*n + 1) {}
Richard Smith84046262013-04-21 01:08:50 +0000753 constexpr operator int() const { return k; }
754 constexpr operator T() const { return T(k); }
Richard Smith7d580a42012-01-17 21:17:26 +0000755 int k;
756};
757
758constexpr bool check(T a, T b) { return a == b.k; }
759
760static_assert(S(5) == 11, "");
761static_assert(check(S(5), 11), "");
762
Richard Smithe9253222012-10-24 23:51:56 +0000763namespace PR14171 {
764
765struct X {
Richard Smith84046262013-04-21 01:08:50 +0000766 constexpr (operator int)() const { return 0; }
Richard Smithe9253222012-10-24 23:51:56 +0000767};
768static_assert(X() == 0, "");
769
770}
771
Richard Smith7d580a42012-01-17 21:17:26 +0000772}
773
Richard Smithe24f5fc2011-11-17 22:56:20 +0000774}
775
776namespace Temporaries {
777
778struct S {
779 constexpr S() {}
Richard Smith84046262013-04-21 01:08:50 +0000780 constexpr int f() const;
Richard Smithe24f5fc2011-11-17 22:56:20 +0000781};
782struct T : S {
783 constexpr T(int n) : S(), n(n) {}
784 int n;
785};
Richard Smith84046262013-04-21 01:08:50 +0000786constexpr int S::f() const {
Richard Smithe24f5fc2011-11-17 22:56:20 +0000787 // 'this' must be the postfix-expression in a class member access expression,
788 // so we can't just use
789 // return static_cast<T*>(this)->n;
790 return this->*(int(S::*))&T::n;
791}
792// The T temporary is implicitly cast to an S subobject, but we can recover the
793// T full-object via a base-to-derived cast, or a derived-to-base-casted member
794// pointer.
Richard Smith9eed49c2011-12-09 23:00:37 +0000795static_assert(T(3).f() == 3, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000796
797constexpr int f(const S &s) {
798 return static_cast<const T&>(s).n;
799}
800constexpr int n = f(T(5));
Richard Smith9eed49c2011-12-09 23:00:37 +0000801static_assert(f(T(5)) == 5, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000802
Richard Smithf2e4cd72012-01-26 04:47:34 +0000803constexpr bool b(int n) { return &n; }
804static_assert(b(0), "");
805
Richard Smith59efe262011-11-11 04:05:33 +0000806}
807
808namespace Union {
809
810union U {
811 int a;
812 int b;
813};
814
Richard Smithd7c56e12011-12-29 21:57:33 +0000815constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } }; // expected-warning 4{{C99 feature}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000816static_assert(u[0].a == 0, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000817static_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 +0000818static_assert(u[1].b == 1, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000819static_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 +0000820static_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 +0000821static_assert((&(u[1]) + 1 + 1)->b == 3, "");
Richard Smith59efe262011-11-11 04:05:33 +0000822
Richard Smithec789162012-01-12 18:54:33 +0000823constexpr U v = {};
824static_assert(v.a == 0, "");
825
826union Empty {};
827constexpr Empty e = {};
828
Richard Smith610a60c2012-01-10 04:32:03 +0000829// Make sure we handle trivial copy constructors for unions.
830constexpr U x = {42};
831constexpr U y = x;
832static_assert(y.a == 42, "");
833static_assert(y.b == 42, ""); // expected-error {{constant expression}} expected-note {{'b' of union with active member 'a'}}
834
Richard Smith59efe262011-11-11 04:05:33 +0000835}
836
Richard Smithe24f5fc2011-11-17 22:56:20 +0000837namespace MemberPointer {
838 struct A {
839 constexpr A(int n) : n(n) {}
840 int n;
Richard Smith84046262013-04-21 01:08:50 +0000841 constexpr int f() const { return n + 3; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000842 };
843 constexpr A a(7);
Richard Smith9eed49c2011-12-09 23:00:37 +0000844 static_assert(A(5).*&A::n == 5, "");
845 static_assert((&a)->*&A::n == 7, "");
846 static_assert((A(8).*&A::f)() == 11, "");
847 static_assert(((&a)->*&A::f)() == 10, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000848
849 struct B : A {
850 constexpr B(int n, int m) : A(n), m(m) {}
851 int m;
Richard Smith84046262013-04-21 01:08:50 +0000852 constexpr int g() const { return n + m + 1; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000853 };
854 constexpr B b(9, 13);
Richard Smith9eed49c2011-12-09 23:00:37 +0000855 static_assert(B(4, 11).*&A::n == 4, "");
856 static_assert(B(4, 11).*&B::m == 11, "");
857 static_assert(B(4, 11).*(int(A::*))&B::m == 11, "");
858 static_assert((&b)->*&A::n == 9, "");
859 static_assert((&b)->*&B::m == 13, "");
860 static_assert((&b)->*(int(A::*))&B::m == 13, "");
861 static_assert((B(4, 11).*&A::f)() == 7, "");
862 static_assert((B(4, 11).*&B::g)() == 16, "");
863 static_assert((B(4, 11).*(int(A::*)()const)&B::g)() == 16, "");
864 static_assert(((&b)->*&A::f)() == 12, "");
865 static_assert(((&b)->*&B::g)() == 23, "");
866 static_assert(((&b)->*(int(A::*)()const)&B::g)() == 23, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000867
868 struct S {
869 constexpr S(int m, int n, int (S::*pf)() const, int S::*pn) :
870 m(m), n(n), pf(pf), pn(pn) {}
871 constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {}
872
Richard Smith84046262013-04-21 01:08:50 +0000873 constexpr int f() const { return this->*pn; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000874 virtual int g() const;
875
876 int m, n;
877 int (S::*pf)() const;
878 int S::*pn;
879 };
880
881 constexpr int S::*pm = &S::m;
882 constexpr int S::*pn = &S::n;
883 constexpr int (S::*pf)() const = &S::f;
884 constexpr int (S::*pg)() const = &S::g;
885
886 constexpr S s(2, 5, &S::f, &S::m);
887
Richard Smith9eed49c2011-12-09 23:00:37 +0000888 static_assert((s.*&S::f)() == 2, "");
889 static_assert((s.*s.pf)() == 2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000890
Richard Smithb02e4622012-02-01 01:42:44 +0000891 static_assert(pf == &S::f, "");
892 static_assert(pf == s.*&S::pf, "");
893 static_assert(pm == &S::m, "");
894 static_assert(pm != pn, "");
895 static_assert(s.pn != pn, "");
896 static_assert(s.pn == pm, "");
897 static_assert(pg != nullptr, "");
898 static_assert(pf != nullptr, "");
899 static_assert((int S::*)nullptr == nullptr, "");
900 static_assert(pg == pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}}
901 static_assert(pf != pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}}
902
Richard Smithe24f5fc2011-11-17 22:56:20 +0000903 template<int n> struct T : T<n-1> {};
904 template<> struct T<0> { int n; };
905 template<> struct T<30> : T<29> { int m; };
906
907 T<17> t17;
908 T<30> t30;
909
910 constexpr int (T<10>::*deepn) = &T<0>::n;
Richard Smith9eed49c2011-12-09 23:00:37 +0000911 static_assert(&(t17.*deepn) == &t17.n, "");
Richard Smithb02e4622012-02-01 01:42:44 +0000912 static_assert(deepn == &T<2>::n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000913
914 constexpr int (T<15>::*deepm) = (int(T<10>::*))&T<30>::m;
915 constexpr int *pbad = &(t17.*deepm); // expected-error {{constant expression}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000916 static_assert(&(t30.*deepm) == &t30.m, "");
Richard Smithb02e4622012-02-01 01:42:44 +0000917 static_assert(deepm == &T<50>::m, "");
918 static_assert(deepm != deepn, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000919
920 constexpr T<5> *p17_5 = &t17;
921 constexpr T<13> *p17_13 = (T<13>*)p17_5;
Richard Smithb4e85ed2012-01-06 16:39:00 +0000922 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 +0000923 static_assert(&(p17_5->*(int(T<3>::*))deepn) == &t17.n, "");
924 static_assert(&(p17_13->*deepn) == &t17.n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000925 constexpr int *pbad2 = &(p17_13->*(int(T<9>::*))deepm); // expected-error {{constant expression}}
926
927 constexpr T<5> *p30_5 = &t30;
928 constexpr T<23> *p30_23 = (T<23>*)p30_5;
929 constexpr T<13> *p30_13 = p30_23;
Richard Smith9eed49c2011-12-09 23:00:37 +0000930 static_assert(&(p30_5->*(int(T<3>::*))deepn) == &t30.n, "");
931 static_assert(&(p30_13->*deepn) == &t30.n, "");
932 static_assert(&(p30_23->*deepn) == &t30.n, "");
933 static_assert(&(p30_5->*(int(T<2>::*))deepm) == &t30.m, "");
934 static_assert(&(((T<17>*)p30_13)->*deepm) == &t30.m, "");
935 static_assert(&(p30_23->*deepm) == &t30.m, "");
Richard Smithb02e4622012-02-01 01:42:44 +0000936
937 struct Base { int n; };
938 template<int N> struct Mid : Base {};
939 struct Derived : Mid<0>, Mid<1> {};
940 static_assert(&Mid<0>::n == &Mid<1>::n, "");
941 static_assert((int Derived::*)(int Mid<0>::*)&Mid<0>::n !=
942 (int Derived::*)(int Mid<1>::*)&Mid<1>::n, "");
943 static_assert(&Mid<0>::n == (int Mid<0>::*)&Base::n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000944}
945
946namespace ArrayBaseDerived {
947
948 struct Base {
949 constexpr Base() {}
950 int n = 0;
951 };
952 struct Derived : Base {
953 constexpr Derived() {}
Richard Smith84046262013-04-21 01:08:50 +0000954 constexpr const int *f() const { return &n; }
Richard Smithe24f5fc2011-11-17 22:56:20 +0000955 };
956
957 constexpr Derived a[10];
958 constexpr Derived *pd3 = const_cast<Derived*>(&a[3]);
959 constexpr Base *pb3 = const_cast<Derived*>(&a[3]);
Richard Smith9eed49c2011-12-09 23:00:37 +0000960 static_assert(pb3 == pd3, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000961
962 // pb3 does not point to an array element.
963 constexpr Base *pb4 = pb3 + 1; // ok, one-past-the-end pointer.
Richard Smithb4e85ed2012-01-06 16:39:00 +0000964 constexpr int pb4n = pb4->n; // expected-error {{constant expression}} expected-note {{cannot access field of pointer past the end}}
965 constexpr Base *err_pb5 = pb3 + 2; // expected-error {{constant expression}} expected-note {{cannot refer to element 2}} expected-note {{here}}
966 constexpr int err_pb5n = err_pb5->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb5' is not a constant expression}}
967 constexpr Base *err_pb2 = pb3 - 1; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} expected-note {{here}}
968 constexpr int err_pb2n = err_pb2->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb2'}}
Richard Smithe24f5fc2011-11-17 22:56:20 +0000969 constexpr Base *pb3a = pb4 - 1;
970
971 // pb4 does not point to a Derived.
Richard Smithb4e85ed2012-01-06 16:39:00 +0000972 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 +0000973 constexpr Derived *pd3a = (Derived*)pb3a;
974 constexpr int pd3n = pd3a->n;
975
976 // pd3a still points to the Derived array.
977 constexpr Derived *pd6 = pd3a + 3;
Richard Smith9eed49c2011-12-09 23:00:37 +0000978 static_assert(pd6 == &a[6], "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000979 constexpr Derived *pd9 = pd6 + 3;
980 constexpr Derived *pd10 = pd6 + 4;
981 constexpr int pd9n = pd9->n; // ok
Richard Smithb4e85ed2012-01-06 16:39:00 +0000982 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 +0000983 constexpr int pd0n = pd10[-10].n;
Richard Smithb4e85ed2012-01-06 16:39:00 +0000984 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 +0000985
986 constexpr Base *pb9 = pd9;
987 constexpr const int *(Base::*pfb)() const =
988 static_cast<const int *(Base::*)() const>(&Derived::f);
Richard Smith9eed49c2011-12-09 23:00:37 +0000989 static_assert((pb9->*pfb)() == &a[9].n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000990}
991
Richard Smith59efe262011-11-11 04:05:33 +0000992namespace Complex {
993
994class complex {
995 int re, im;
996public:
997 constexpr complex(int re = 0, int im = 0) : re(re), im(im) {}
998 constexpr complex(const complex &o) : re(o.re), im(o.im) {}
999 constexpr complex operator-() const { return complex(-re, -im); }
1000 friend constexpr complex operator+(const complex &l, const complex &r) {
1001 return complex(l.re + r.re, l.im + r.im);
1002 }
1003 friend constexpr complex operator-(const complex &l, const complex &r) {
1004 return l + -r;
1005 }
1006 friend constexpr complex operator*(const complex &l, const complex &r) {
1007 return complex(l.re * r.re - l.im * r.im, l.re * r.im + l.im * r.re);
1008 }
1009 friend constexpr bool operator==(const complex &l, const complex &r) {
1010 return l.re == r.re && l.im == r.im;
1011 }
1012 constexpr bool operator!=(const complex &r) const {
1013 return re != r.re || im != r.im;
1014 }
1015 constexpr int real() const { return re; }
1016 constexpr int imag() const { return im; }
1017};
1018
1019constexpr complex i = complex(0, 1);
1020constexpr complex k = (3 + 4*i) * (6 - 4*i);
Richard Smith9eed49c2011-12-09 23:00:37 +00001021static_assert(complex(1,0).real() == 1, "");
1022static_assert(complex(1,0).imag() == 0, "");
1023static_assert(((complex)1).imag() == 0, "");
1024static_assert(k.real() == 34, "");
1025static_assert(k.imag() == 12, "");
1026static_assert(k - 34 == 12*i, "");
1027static_assert((complex)1 == complex(1), "");
1028static_assert((complex)1 != complex(0, 1), "");
1029static_assert(complex(1) == complex(1), "");
1030static_assert(complex(1) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001031constexpr complex makeComplex(int re, int im) { return complex(re, im); }
Richard Smith9eed49c2011-12-09 23:00:37 +00001032static_assert(makeComplex(1,0) == complex(1), "");
1033static_assert(makeComplex(1,0) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001034
1035class complex_wrap : public complex {
1036public:
1037 constexpr complex_wrap(int re, int im = 0) : complex(re, im) {}
1038 constexpr complex_wrap(const complex_wrap &o) : complex(o) {}
1039};
1040
Richard Smith9eed49c2011-12-09 23:00:37 +00001041static_assert((complex_wrap)1 == complex(1), "");
1042static_assert((complex)1 != complex_wrap(0, 1), "");
1043static_assert(complex(1) == complex_wrap(1), "");
1044static_assert(complex_wrap(1) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001045constexpr complex_wrap makeComplexWrap(int re, int im) {
1046 return complex_wrap(re, im);
1047}
Richard Smith9eed49c2011-12-09 23:00:37 +00001048static_assert(makeComplexWrap(1,0) == complex(1), "");
1049static_assert(makeComplexWrap(1,0) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001050
1051}
Eli Friedmanf59ff8c2011-12-17 02:24:21 +00001052
1053namespace PR11595 {
Richard Smith84046262013-04-21 01:08:50 +00001054 struct A { constexpr bool operator==(int x) const { return true; } };
Richard Smithaf2c7a12011-12-19 22:01:37 +00001055 struct B { B(); A& x; };
1056 static_assert(B().x == 3, ""); // expected-error {{constant expression}} expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
1057
Richard Smith745f5142012-01-27 01:14:48 +00001058 constexpr bool f(int k) { // expected-error {{constexpr function never produces a constant expression}}
Richard Smithaf2c7a12011-12-19 22:01:37 +00001059 return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
1060 }
Eli Friedmanf59ff8c2011-12-17 02:24:21 +00001061}
Richard Smithbc6abe92011-12-19 22:12:41 +00001062
1063namespace ExprWithCleanups {
1064 struct A { A(); ~A(); int get(); };
1065 constexpr int get(bool FromA) { return FromA ? A().get() : 1; }
1066 constexpr int n = get(false);
1067}
Richard Smith7098cbd2011-12-21 05:04:46 +00001068
1069namespace Volatile {
1070
1071volatile constexpr int n1 = 0; // expected-note {{here}}
1072volatile const int n2 = 0; // expected-note {{here}}
1073int n3 = 37; // expected-note {{declared here}}
1074
Richard Smith9ec71972012-02-05 01:23:16 +00001075constexpr int m1 = n1; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
1076constexpr int m2 = n2; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
1077constexpr int m1b = const_cast<const int&>(n1); // expected-error {{constant expression}} expected-note {{read of volatile object 'n1'}}
1078constexpr 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 +00001079
1080struct T { int n; };
1081const T t = { 42 }; // expected-note {{declared here}}
1082
1083constexpr int f(volatile int &&r) {
Richard Smith9ec71972012-02-05 01:23:16 +00001084 return r; // expected-note {{read of volatile-qualified type 'volatile int'}}
1085}
1086constexpr int g(volatile int &&r) {
1087 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 +00001088}
1089struct S {
Richard Smith9ec71972012-02-05 01:23:16 +00001090 int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}}
1091 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 +00001092 int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}}
1093 int m : t.n; // expected-error {{constant expression}} expected-note {{read of non-constexpr variable}}
1094};
1095
1096}
Richard Smithdd4b3502011-12-25 21:17:58 +00001097
1098namespace ExternConstexpr {
1099 extern constexpr int n = 0;
1100 extern constexpr int m; // expected-error {{constexpr variable declaration must be a definition}}
1101 void f() {
1102 extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}}
1103 constexpr int j = 0;
1104 constexpr int k; // expected-error {{default initialization of an object of const type}}
1105 }
1106}
Eli Friedman7ead5c72012-01-10 04:58:17 +00001107
1108namespace ComplexConstexpr {
1109 constexpr _Complex float test1 = {};
1110 constexpr _Complex float test2 = {1};
1111 constexpr _Complex double test3 = {1,2};
1112 constexpr _Complex int test4 = {4};
1113 constexpr _Complex int test5 = 4;
1114 constexpr _Complex int test6 = {5,6};
Eli Friedmanf6c17a42012-01-13 23:34:56 +00001115 typedef _Complex float fcomplex;
1116 constexpr fcomplex test7 = fcomplex();
Richard Smith86024012012-02-18 22:04:06 +00001117
1118 constexpr const double &t2r = __real test3;
1119 constexpr const double &t2i = __imag test3;
1120 static_assert(&t2r + 1 == &t2i, "");
1121 static_assert(t2r == 1.0, "");
1122 static_assert(t2i == 2.0, "");
1123 constexpr const double *t2p = &t2r;
1124 static_assert(t2p[-1] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element -1 of array of 2 elements}}
1125 static_assert(t2p[0] == 1.0, "");
1126 static_assert(t2p[1] == 2.0, "");
1127 static_assert(t2p[2] == 0.0, ""); // expected-error {{constant expr}} expected-note {{one-past-the-end pointer}}
1128 static_assert(t2p[3] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element 3 of array of 2 elements}}
1129 constexpr _Complex float *p = 0;
1130 constexpr float pr = __real *p; // expected-error {{constant expr}} expected-note {{cannot access real component of null}}
1131 constexpr float pi = __imag *p; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of null}}
1132 constexpr const _Complex double *q = &test3 + 1;
1133 constexpr double qr = __real *q; // expected-error {{constant expr}} expected-note {{cannot access real component of pointer past the end}}
1134 constexpr double qi = __imag *q; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of pointer past the end}}
1135
1136 static_assert(__real test6 == 5, "");
1137 static_assert(__imag test6 == 6, "");
1138 static_assert(&__imag test6 == &__real test6 + 1, "");
Eli Friedman7ead5c72012-01-10 04:58:17 +00001139}
Eli Friedman6b3014b2012-01-18 02:54:10 +00001140
1141namespace InstantiateCaseStmt {
1142 template<int x> constexpr int f() { return x; }
1143 template<int x> int g(int c) { switch(c) { case f<x>(): return 1; } return 0; }
1144 int gg(int c) { return g<4>(c); }
1145}
Richard Smith495f42a2012-01-24 05:40:50 +00001146
1147namespace ConvertedConstantExpr {
1148 extern int &m;
1149 extern int &n;
1150
1151 constexpr int k = 4;
1152 int &m = const_cast<int&>(k);
1153
1154 // If we have nothing more interesting to say, ensure we don't produce a
1155 // useless note and instead just point to the non-constant subexpression.
1156 enum class E {
1157 em = m,
1158 en = n, // expected-error {{not a constant expression}}
1159 eo = (m +
1160 n // expected-error {{not a constant expression}}
1161 ),
1162 eq = reinterpret_cast<int>((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}}
1163 };
1164}
Richard Smithd9b02e72012-01-25 22:15:11 +00001165
1166namespace IndirectField {
1167 struct S {
1168 struct { // expected-warning {{GNU extension}}
Richard Smithf2705192013-01-31 03:11:12 +00001169 union { // expected-warning {{declared in an anonymous struct}}
1170 struct { // expected-warning {{GNU extension}} expected-warning {{declared in an anonymous union}}
Richard Smithd9b02e72012-01-25 22:15:11 +00001171 int a;
1172 int b;
1173 };
1174 int c;
1175 };
1176 int d;
1177 };
1178 union {
1179 int e;
1180 int f;
1181 };
1182 constexpr S(int a, int b, int d, int e) : a(a), b(b), d(d), e(e) {}
1183 constexpr S(int c, int d, int f) : c(c), d(d), f(f) {}
1184 };
1185
1186 constexpr S s1(1, 2, 3, 4);
1187 constexpr S s2(5, 6, 7);
1188
1189 // FIXME: The diagnostics here do a very poor job of explaining which unnamed
1190 // member is active and which is requested.
1191 static_assert(s1.a == 1, "");
1192 static_assert(s1.b == 2, "");
1193 static_assert(s1.c == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1194 static_assert(s1.d == 3, "");
1195 static_assert(s1.e == 4, "");
1196 static_assert(s1.f == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1197
1198 static_assert(s2.a == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1199 static_assert(s2.b == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1200 static_assert(s2.c == 5, "");
1201 static_assert(s2.d == 6, "");
1202 static_assert(s2.e == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1203 static_assert(s2.f == 7, "");
1204}
Richard Smithf15fda02012-02-02 01:16:57 +00001205
Richard Smithb4e5e282012-02-09 03:29:58 +00001206// DR1405: don't allow reading mutable members in constant expressions.
1207namespace MutableMembers {
1208 struct MM {
1209 mutable int n; // expected-note 3{{declared here}}
1210 } constexpr mm = { 4 };
1211 constexpr int mmn = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
1212 int x = (mm.n = 1, 3);
1213 constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
1214
1215 // Here's one reason why allowing this would be a disaster...
1216 template<int n> struct Id { int k = n; };
1217 int f() {
1218 constexpr MM m = { 0 };
1219 ++m.n;
1220 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}}
1221 }
1222
1223 struct A { int n; };
1224 struct B { mutable A a; }; // expected-note {{here}}
1225 struct C { B b; };
1226 constexpr C c[3] = {};
1227 constexpr int k = c[1].b.a.n; // expected-error {{constant expression}} expected-note {{mutable}}
1228}
1229
Richard Smithf15fda02012-02-02 01:16:57 +00001230namespace Fold {
1231
1232 // This macro forces its argument to be constant-folded, even if it's not
1233 // otherwise a constant expression.
1234 #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
1235
1236 constexpr int n = (int)(char*)123; // expected-error {{constant expression}} expected-note {{reinterpret_cast}}
1237 constexpr int m = fold((int)(char*)123); // ok
1238 static_assert(m == 123, "");
1239
1240 #undef fold
1241
1242}
Richard Smith83587db2012-02-15 02:18:13 +00001243
1244namespace DR1454 {
1245
1246constexpr const int &f(const int &n) { return n; }
1247constexpr int k1 = f(0); // ok
1248
1249struct Wrap {
1250 const int &value;
1251};
1252constexpr const Wrap &g(const Wrap &w) { return w; }
1253constexpr int k2 = g({0}).value; // ok
1254
1255constexpr const int &i = 0; // expected-error {{constant expression}} expected-note {{temporary}} expected-note 2{{here}}
1256constexpr const int j = i; // expected-error {{constant expression}} expected-note {{initializer of 'i' is not a constant expression}}
1257
1258}
Richard Smith74e1ad92012-02-16 02:46:34 +00001259
1260namespace RecursiveOpaqueExpr {
1261 template<typename Iter>
1262 constexpr auto LastNonzero(Iter p, Iter q) -> decltype(+*p) {
1263 return p != q ? (LastNonzero(p+1, q) ?: *p) : 0; // expected-warning {{GNU}}
1264 }
1265
1266 constexpr int arr1[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 0 };
1267 static_assert(LastNonzero(begin(arr1), end(arr1)) == 4, "");
1268
1269 constexpr int arr2[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 5 };
1270 static_assert(LastNonzero(begin(arr2), end(arr2)) == 5, "");
Richard Smithe92b1f42012-06-26 08:12:11 +00001271
1272 constexpr int arr3[] = {
1273 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,
1274 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,
1275 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,
1276 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,
1277 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,
1278 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,
1279 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,
1280 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 };
1281 static_assert(LastNonzero(begin(arr3), end(arr3)) == 2, "");
Richard Smith74e1ad92012-02-16 02:46:34 +00001282}
1283
1284namespace VLASizeof {
1285
1286 void f(int k) {
1287 int arr[k]; // expected-warning {{C99}}
1288 constexpr int n = 1 +
1289 sizeof(arr) // expected-error {{constant expression}}
1290 * 3;
1291 }
1292}
Richard Smithb78ae972012-02-18 04:58:18 +00001293
1294namespace CompoundLiteral {
1295 // FIXME:
1296 // We don't model the semantics of this correctly: the compound literal is
1297 // represented as a prvalue in the AST, but actually behaves like an lvalue.
1298 // We treat the compound literal as a temporary and refuse to produce a
1299 // pointer to it. This is OK: we're not required to treat this as a constant
1300 // in C++, and in C we model compound literals as lvalues.
1301 constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}}
1302}
Richard Smith4b1f6842012-03-13 20:58:32 +00001303
1304namespace Vector {
1305 typedef int __attribute__((vector_size(16))) VI4;
1306 constexpr VI4 f(int n) {
1307 return VI4 { n * 3, n + 4, n - 5, n / 6 };
1308 }
1309 constexpr auto v1 = f(10);
1310
1311 typedef double __attribute__((vector_size(32))) VD4;
1312 constexpr VD4 g(int n) {
1313 return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 }; // expected-warning {{C99}}
1314 }
1315 constexpr auto v2 = g(4);
1316}
John McCall8d59dee2012-05-01 00:38:49 +00001317
1318// PR12626, redux
1319namespace InvalidClasses {
1320 void test0() {
1321 struct X; // expected-note {{forward declaration}}
1322 struct Y { bool b; X x; }; // expected-error {{field has incomplete type}}
1323 Y y;
1324 auto& b = y.b;
1325 }
1326}
Richard Smithdbbeccc2012-05-15 05:04:02 +00001327
Richard Smitha10b9782013-04-22 15:31:51 +00001328namespace NamespaceAlias {
1329 constexpr int f() {
1330 namespace NS = NamespaceAlias; // expected-warning {{use of this statement in a constexpr function is a C++1y extension}}
1331 return &NS::f != nullptr;
1332 }
1333}
1334
Richard Smith622da852012-07-02 06:15:40 +00001335// Constructors can be implicitly constexpr, even for a non-literal type.
1336namespace ImplicitConstexpr {
1337 struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}}
Richard Smith604fb382012-08-07 22:06:48 +00001338 struct R { constexpr R() noexcept; constexpr R(const R&) noexcept; constexpr R(R&&) noexcept; ~R() noexcept; };
Richard Smith622da852012-07-02 06:15:40 +00001339 struct S { R r; }; // expected-note 3{{here}}
Richard Smith604fb382012-08-07 22:06:48 +00001340 struct T { T(const T&) noexcept; T(T &&) noexcept; ~T() noexcept; };
Richard Smith622da852012-07-02 06:15:40 +00001341 struct U { T t; }; // expected-note 3{{here}}
1342 static_assert(!__is_literal_type(Q), "");
1343 static_assert(!__is_literal_type(R), "");
1344 static_assert(!__is_literal_type(S), "");
1345 static_assert(!__is_literal_type(T), "");
1346 static_assert(!__is_literal_type(U), "");
1347 struct Test {
1348 friend Q::Q() noexcept; // expected-error {{follows constexpr}}
1349 friend Q::Q(Q&&) noexcept; // expected-error {{follows constexpr}}
1350 friend Q::Q(const Q&) noexcept; // expected-error {{follows constexpr}}
1351 friend S::S() noexcept; // expected-error {{follows constexpr}}
1352 friend S::S(S&&) noexcept; // expected-error {{follows constexpr}}
1353 friend S::S(const S&) noexcept; // expected-error {{follows constexpr}}
1354 friend constexpr U::U() noexcept; // expected-error {{follows non-constexpr}}
1355 friend constexpr U::U(U&&) noexcept; // expected-error {{follows non-constexpr}}
1356 friend constexpr U::U(const U&) noexcept; // expected-error {{follows non-constexpr}}
1357 };
1358}
1359
Richard Smithdbbeccc2012-05-15 05:04:02 +00001360// Indirectly test that an implicit lvalue to xvalue conversion performed for
1361// an NRVO move operation isn't implemented as CK_LValueToRValue.
1362namespace PR12826 {
1363 struct Foo {};
1364 constexpr Foo id(Foo x) { return x; }
1365 constexpr Foo res(id(Foo()));
1366}
Richard Smithf4bb8d02012-07-05 08:39:21 +00001367
1368namespace PR13273 {
1369 struct U {
1370 int t;
1371 U() = default;
1372 };
1373
1374 struct S : U {
1375 S() = default;
1376 };
1377
1378 // S's default constructor isn't constexpr, because U's default constructor
1379 // doesn't initialize 't', but it's trivial, so value-initialization doesn't
1380 // actually call it.
1381 static_assert(S{}.t == 0, "");
1382}
Richard Smith20599392012-07-07 08:35:56 +00001383
1384namespace PR12670 {
1385 struct S {
1386 constexpr S(int a0) : m(a0) {}
1387 constexpr S() : m(6) {}
1388 int m;
1389 };
1390 constexpr S x[3] = { {4}, 5 };
1391 static_assert(x[0].m == 4, "");
1392 static_assert(x[1].m == 5, "");
1393 static_assert(x[2].m == 6, "");
1394}
Richard Smith604fb382012-08-07 22:06:48 +00001395
1396// Indirectly test that an implicit lvalue-to-rvalue conversion is performed
1397// when a conditional operator has one argument of type void and where the other
1398// is a glvalue of class type.
1399namespace ConditionalLValToRVal {
1400 struct A {
1401 constexpr A(int a) : v(a) {}
1402 int v;
1403 };
1404
1405 constexpr A f(const A &a) {
1406 return a.v == 0 ? throw a : a;
1407 }
1408
1409 constexpr A a(4);
1410 static_assert(f(a).v == 4, "");
1411}
Hans Wennborg29f431b2012-08-29 09:17:34 +00001412
1413namespace TLS {
1414 __thread int n;
Hans Wennborg48def652012-08-29 18:27:29 +00001415 int m;
1416
1417 constexpr bool b = &n == &n;
1418
1419 constexpr int *p = &n; // expected-error{{constexpr variable 'p' must be initialized by a constant expression}}
1420
1421 constexpr int *f() { return &n; }
1422 constexpr int *q = f(); // expected-error{{constexpr variable 'q' must be initialized by a constant expression}}
1423 constexpr bool c = f() == f();
1424
1425 constexpr int *g() { return &m; }
1426 constexpr int *r = g();
Hans Wennborg29f431b2012-08-29 09:17:34 +00001427}
Richard Smith01cad022012-10-01 20:36:17 +00001428
1429namespace Void {
1430 constexpr void f() { return; } // expected-error{{constexpr function's return type 'void' is not a literal type}}
1431
1432 void assert_failed(const char *msg, const char *file, int line); // expected-note {{declared here}}
1433#define ASSERT(expr) ((expr) ? static_cast<void>(0) : assert_failed(#expr, __FILE__, __LINE__))
1434 template<typename T, size_t S>
1435 constexpr T get(T (&a)[S], size_t k) {
1436 return ASSERT(k > 0 && k < S), a[k]; // expected-note{{non-constexpr function 'assert_failed'}}
1437 }
1438#undef ASSERT
1439 template int get(int (&a)[4], size_t);
1440 constexpr int arr[] = { 4, 1, 2, 3, 4 };
1441 static_assert(get(arr, 1) == 1, "");
1442 static_assert(get(arr, 4) == 4, "");
1443 static_assert(get(arr, 0) == 4, ""); // expected-error{{not an integral constant expression}} \
1444 // expected-note{{in call to 'get(arr, 0)'}}
1445}
Richard Smith9be36ab2012-10-17 23:52:07 +00001446
1447namespace std { struct type_info; }
1448
1449namespace TypeId {
1450 struct A { virtual ~A(); };
1451 A f();
1452 A &g();
1453 constexpr auto &x = typeid(f());
1454 constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \
1455 // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}}
1456}
Richard Smith9568f0c2012-10-29 18:26:47 +00001457
1458namespace PR14203 {
1459 struct duration {
1460 constexpr duration() {}
1461 constexpr operator int() const { return 0; }
1462 };
1463 template<typename T> void f() {
1464 // If we want to evaluate this at the point of the template definition, we
1465 // need to trigger the implicit definition of the move constructor at that
1466 // point.
1467 // FIXME: C++ does not permit us to implicitly define it at the appropriate
1468 // times, since it is only allowed to be implicitly defined when it is
1469 // odr-used.
1470 constexpr duration d = duration();
1471 }
1472 // FIXME: It's unclear whether this is valid. On the one hand, we're not
1473 // allowed to generate a move constructor. On the other hand, if we did,
Richard Smithce2661f2012-11-07 01:14:25 +00001474 // this would be a constant expression. For now, we generate a move
1475 // constructor here.
1476 int n = sizeof(short{duration(duration())});
Richard Smith9568f0c2012-10-29 18:26:47 +00001477}
Richard Smith99ad3592013-04-22 14:44:29 +00001478
1479namespace ArrayEltInit {
1480 struct A {
1481 constexpr A() : p(&p) {}
1482 void *p;
1483 };
1484 constexpr A a[10];
1485 static_assert(a[0].p == &a[0].p, "");
1486 static_assert(a[9].p == &a[9].p, "");
1487 static_assert(a[0].p != &a[9].p, "");
1488 static_assert(a[9].p != &a[0].p, "");
1489
1490 constexpr A b[10] = {};
1491 static_assert(b[0].p == &b[0].p, "");
1492 static_assert(b[9].p == &b[9].p, "");
1493 static_assert(b[0].p != &b[9].p, "");
1494 static_assert(b[9].p != &b[0].p, "");
1495}
Richard Smitha07a6c32013-05-01 19:00:39 +00001496
1497namespace PR15884 {
1498 struct S {};
1499 constexpr S f() { return {}; }
1500 constexpr S *p = &f();
1501 // expected-error@-1 {{taking the address of a temporary}}
1502 // expected-error@-2 {{constexpr variable 'p' must be initialized by a constant expression}}
1503 // expected-note@-3 {{pointer to temporary is not a constant expression}}
1504 // expected-note@-4 {{temporary created here}}
1505}