blob: f576dfa32f29148a733ef97dcf16f192b38fd14b [file] [log] [blame]
Nico Weber1cb2d742012-03-02 22:01:22 +00001// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -fsyntax-only -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 {
24 constexpr int zero() { return 0; }
25};
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;
489 constexpr int f() { return n; }
490};
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 Smith59efe262011-11-11 04:05:33 +0000510}
511
512namespace DependentValues {
513
514struct I { int n; typedef I V[10]; };
515I::V x, y;
516template<bool B> struct S {
517 int k;
518 void f() {
519 I::V &cells = B ? x : y;
520 I &i = cells[k];
521 switch (i.n) {}
522 }
523};
524
525}
526
527namespace Class {
528
529struct A { constexpr A(int a, int b) : k(a + b) {} int k; };
530constexpr int fn(const A &a) { return a.k; }
Richard Smith9eed49c2011-12-09 23:00:37 +0000531static_assert(fn(A(4,5)) == 9, "");
Richard Smith59efe262011-11-11 04:05:33 +0000532
533struct B { int n; int m; } constexpr b = { 0, b.n }; // expected-warning {{uninitialized}}
534struct C {
535 constexpr C(C *this_) : m(42), n(this_->m) {} // ok
536 int m, n;
537};
538struct D {
539 C c;
540 constexpr D() : c(&c) {}
541};
Richard Smith9eed49c2011-12-09 23:00:37 +0000542static_assert(D().c.n == 42, "");
Richard Smith59efe262011-11-11 04:05:33 +0000543
Richard Smith61802452011-12-22 02:22:31 +0000544struct E {
Richard Smith83587db2012-02-15 02:18:13 +0000545 constexpr E() : p(&p) {}
Richard Smith59efe262011-11-11 04:05:33 +0000546 void *p;
547};
Richard Smith83587db2012-02-15 02:18:13 +0000548constexpr 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 +0000549// This is a constant expression if we elide the copy constructor call, and
550// is not a constant expression if we don't! But we do, so it is.
Richard Smith61802452011-12-22 02:22:31 +0000551constexpr E e2 = E();
552static_assert(e2.p == &e2.p, "");
Richard Smith099e7f62011-12-19 06:19:21 +0000553constexpr E e3;
Richard Smith9eed49c2011-12-09 23:00:37 +0000554static_assert(e3.p == &e3.p, "");
Richard Smith59efe262011-11-11 04:05:33 +0000555
556extern const class F f;
557struct F {
558 constexpr F() : p(&f.p) {}
559 const void *p;
560};
Richard Smith099e7f62011-12-19 06:19:21 +0000561constexpr F f;
Richard Smith59efe262011-11-11 04:05:33 +0000562
563struct G {
564 struct T {
565 constexpr T(T *p) : u1(), u2(p) {}
566 union U1 {
567 constexpr U1() {}
568 int a, b = 42;
569 } u1;
570 union U2 {
571 constexpr U2(T *p) : c(p->u1.b) {}
572 int c, d;
573 } u2;
574 } t;
575 constexpr G() : t(&t) {}
576} constexpr g;
577
Richard Smith7098cbd2011-12-21 05:04:46 +0000578static_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 +0000579static_assert(g.t.u1.b == 42, "");
580static_assert(g.t.u2.c == 42, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000581static_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 +0000582
583struct S {
584 int a, b;
585 const S *p;
586 double d;
587 const char *q;
588
589 constexpr S(int n, const S *p) : a(5), b(n), p(p), d(n), q("hello") {}
590};
591
592S global(43, &global);
593
Richard Smith9eed49c2011-12-09 23:00:37 +0000594static_assert(S(15, &global).b == 15, "");
Richard Smith59efe262011-11-11 04:05:33 +0000595
596constexpr bool CheckS(const S &s) {
597 return s.a == 5 && s.b == 27 && s.p == &global && s.d == 27. && s.q[3] == 'l';
598}
Richard Smith9eed49c2011-12-09 23:00:37 +0000599static_assert(CheckS(S(27, &global)), "");
Richard Smith59efe262011-11-11 04:05:33 +0000600
601struct Arr {
602 char arr[3];
603 constexpr Arr() : arr{'x', 'y', 'z'} {}
604};
605constexpr int hash(Arr &&a) {
606 return a.arr[0] + a.arr[1] * 0x100 + a.arr[2] * 0x10000;
607}
608constexpr int k = hash(Arr());
Richard Smith9eed49c2011-12-09 23:00:37 +0000609static_assert(k == 0x007a7978, "");
Richard Smith59efe262011-11-11 04:05:33 +0000610
611
612struct AggregateInit {
613 const char &c;
614 int n;
615 double d;
616 int arr[5];
617 void *p;
618};
619
620constexpr AggregateInit agg1 = { "hello"[0] };
621
Richard Smith9eed49c2011-12-09 23:00:37 +0000622static_assert(strcmp_ce(&agg1.c, "hello") == 0, "");
623static_assert(agg1.n == 0, "");
624static_assert(agg1.d == 0.0, "");
Richard Smithb4e85ed2012-01-06 16:39:00 +0000625static_assert(agg1.arr[-1] == 0, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000626static_assert(agg1.arr[0] == 0, "");
627static_assert(agg1.arr[4] == 0, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000628static_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 +0000629static_assert(agg1.p == nullptr, "");
Richard Smith59efe262011-11-11 04:05:33 +0000630
Richard Smithfe587202012-04-15 02:50:59 +0000631static constexpr const unsigned char uc[] = { "foo" };
632static_assert(uc[0] == 'f', "");
633static_assert(uc[3] == 0, "");
634
Richard Smith59efe262011-11-11 04:05:33 +0000635namespace SimpleDerivedClass {
636
637struct B {
638 constexpr B(int n) : a(n) {}
639 int a;
640};
641struct D : B {
642 constexpr D(int n) : B(n) {}
643};
644constexpr D d(3);
Richard Smith9eed49c2011-12-09 23:00:37 +0000645static_assert(d.a == 3, "");
Richard Smith59efe262011-11-11 04:05:33 +0000646
647}
648
Richard Smithe24f5fc2011-11-17 22:56:20 +0000649struct Bottom { constexpr Bottom() {} };
650struct Base : Bottom {
Richard Smith59efe262011-11-11 04:05:33 +0000651 constexpr Base(int a = 42, const char *b = "test") : a(a), b(b) {}
652 int a;
653 const char *b;
654};
Richard Smithe24f5fc2011-11-17 22:56:20 +0000655struct Base2 : Bottom {
Richard Smith59efe262011-11-11 04:05:33 +0000656 constexpr Base2(const int &r) : r(r) {}
657 int q = 123;
Richard Smith099e7f62011-12-19 06:19:21 +0000658 const int &r;
Richard Smith59efe262011-11-11 04:05:33 +0000659};
660struct Derived : Base, Base2 {
661 constexpr Derived() : Base(76), Base2(a) {}
662 int c = r + b[1];
663};
664
665constexpr bool operator==(const Base &a, const Base &b) {
666 return a.a == b.a && strcmp_ce(a.b, b.b) == 0;
667}
668
669constexpr Base base;
670constexpr Base base2(76);
671constexpr Derived derived;
Richard Smith9eed49c2011-12-09 23:00:37 +0000672static_assert(derived.a == 76, "");
673static_assert(derived.b[2] == 's', "");
674static_assert(derived.c == 76 + 'e', "");
675static_assert(derived.q == 123, "");
676static_assert(derived.r == 76, "");
Richard Smith099e7f62011-12-19 06:19:21 +0000677static_assert(&derived.r == &derived.a, "");
Richard Smith59efe262011-11-11 04:05:33 +0000678
Richard Smith9eed49c2011-12-09 23:00:37 +0000679static_assert(!(derived == base), "");
680static_assert(derived == base2, "");
Richard Smith59efe262011-11-11 04:05:33 +0000681
Richard Smithe24f5fc2011-11-17 22:56:20 +0000682constexpr Bottom &bot1 = (Base&)derived;
683constexpr Bottom &bot2 = (Base2&)derived;
Richard Smith9eed49c2011-12-09 23:00:37 +0000684static_assert(&bot1 != &bot2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000685
686constexpr Bottom *pb1 = (Base*)&derived;
687constexpr Bottom *pb2 = (Base2*)&derived;
Richard Smithf15fda02012-02-02 01:16:57 +0000688static_assert(&pb1 != &pb2, "");
Richard Smith9eed49c2011-12-09 23:00:37 +0000689static_assert(pb1 == &bot1, "");
690static_assert(pb2 == &bot2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000691
Richard Smithb4e85ed2012-01-06 16:39:00 +0000692constexpr Base2 &fail = (Base2&)bot1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}}
693constexpr 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 +0000694constexpr Base2 &ok2 = (Base2&)bot2;
Richard Smith9eed49c2011-12-09 23:00:37 +0000695static_assert(&ok2 == &derived, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000696
Richard Smithb4e85ed2012-01-06 16:39:00 +0000697constexpr Base2 *pfail = (Base2*)pb1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}}
698constexpr 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 +0000699constexpr Base2 *pok2 = (Base2*)pb2;
Richard Smith9eed49c2011-12-09 23:00:37 +0000700static_assert(pok2 == &derived, "");
701static_assert(&ok2 == pok2, "");
702static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");
703static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000704
705constexpr Base *nullB = 42 - 6 * 7;
Richard Smith9eed49c2011-12-09 23:00:37 +0000706static_assert((Bottom*)nullB == 0, "");
707static_assert((Derived*)nullB == 0, "");
708static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000709
Richard Smith7d580a42012-01-17 21:17:26 +0000710namespace ConversionOperators {
711
712struct T {
713 constexpr T(int n) : k(5*n - 3) {}
714 constexpr operator int() { return k; }
715 int k;
716};
717
718struct S {
719 constexpr S(int n) : k(2*n + 1) {}
720 constexpr operator int() { return k; }
721 constexpr operator T() { return T(k); }
722 int k;
723};
724
725constexpr bool check(T a, T b) { return a == b.k; }
726
727static_assert(S(5) == 11, "");
728static_assert(check(S(5), 11), "");
729
730}
731
Richard Smithe24f5fc2011-11-17 22:56:20 +0000732}
733
734namespace Temporaries {
735
736struct S {
737 constexpr S() {}
738 constexpr int f();
739};
740struct T : S {
741 constexpr T(int n) : S(), n(n) {}
742 int n;
743};
744constexpr int S::f() {
745 // 'this' must be the postfix-expression in a class member access expression,
746 // so we can't just use
747 // return static_cast<T*>(this)->n;
748 return this->*(int(S::*))&T::n;
749}
750// The T temporary is implicitly cast to an S subobject, but we can recover the
751// T full-object via a base-to-derived cast, or a derived-to-base-casted member
752// pointer.
Richard Smith9eed49c2011-12-09 23:00:37 +0000753static_assert(T(3).f() == 3, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000754
755constexpr int f(const S &s) {
756 return static_cast<const T&>(s).n;
757}
758constexpr int n = f(T(5));
Richard Smith9eed49c2011-12-09 23:00:37 +0000759static_assert(f(T(5)) == 5, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000760
Richard Smithf2e4cd72012-01-26 04:47:34 +0000761constexpr bool b(int n) { return &n; }
762static_assert(b(0), "");
763
Richard Smith59efe262011-11-11 04:05:33 +0000764}
765
766namespace Union {
767
768union U {
769 int a;
770 int b;
771};
772
Richard Smithd7c56e12011-12-29 21:57:33 +0000773constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } }; // expected-warning 4{{C99 feature}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000774static_assert(u[0].a == 0, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000775static_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 +0000776static_assert(u[1].b == 1, "");
Richard Smith7098cbd2011-12-21 05:04:46 +0000777static_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 +0000778static_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 +0000779static_assert((&(u[1]) + 1 + 1)->b == 3, "");
Richard Smith59efe262011-11-11 04:05:33 +0000780
Richard Smithec789162012-01-12 18:54:33 +0000781constexpr U v = {};
782static_assert(v.a == 0, "");
783
784union Empty {};
785constexpr Empty e = {};
786
Richard Smith610a60c2012-01-10 04:32:03 +0000787// Make sure we handle trivial copy constructors for unions.
788constexpr U x = {42};
789constexpr U y = x;
790static_assert(y.a == 42, "");
791static_assert(y.b == 42, ""); // expected-error {{constant expression}} expected-note {{'b' of union with active member 'a'}}
792
Richard Smith59efe262011-11-11 04:05:33 +0000793}
794
Richard Smithe24f5fc2011-11-17 22:56:20 +0000795namespace MemberPointer {
796 struct A {
797 constexpr A(int n) : n(n) {}
798 int n;
799 constexpr int f() { return n + 3; }
800 };
801 constexpr A a(7);
Richard Smith9eed49c2011-12-09 23:00:37 +0000802 static_assert(A(5).*&A::n == 5, "");
803 static_assert((&a)->*&A::n == 7, "");
804 static_assert((A(8).*&A::f)() == 11, "");
805 static_assert(((&a)->*&A::f)() == 10, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000806
807 struct B : A {
808 constexpr B(int n, int m) : A(n), m(m) {}
809 int m;
810 constexpr int g() { return n + m + 1; }
811 };
812 constexpr B b(9, 13);
Richard Smith9eed49c2011-12-09 23:00:37 +0000813 static_assert(B(4, 11).*&A::n == 4, "");
814 static_assert(B(4, 11).*&B::m == 11, "");
815 static_assert(B(4, 11).*(int(A::*))&B::m == 11, "");
816 static_assert((&b)->*&A::n == 9, "");
817 static_assert((&b)->*&B::m == 13, "");
818 static_assert((&b)->*(int(A::*))&B::m == 13, "");
819 static_assert((B(4, 11).*&A::f)() == 7, "");
820 static_assert((B(4, 11).*&B::g)() == 16, "");
821 static_assert((B(4, 11).*(int(A::*)()const)&B::g)() == 16, "");
822 static_assert(((&b)->*&A::f)() == 12, "");
823 static_assert(((&b)->*&B::g)() == 23, "");
824 static_assert(((&b)->*(int(A::*)()const)&B::g)() == 23, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000825
826 struct S {
827 constexpr S(int m, int n, int (S::*pf)() const, int S::*pn) :
828 m(m), n(n), pf(pf), pn(pn) {}
829 constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {}
830
831 constexpr int f() { return this->*pn; }
832 virtual int g() const;
833
834 int m, n;
835 int (S::*pf)() const;
836 int S::*pn;
837 };
838
839 constexpr int S::*pm = &S::m;
840 constexpr int S::*pn = &S::n;
841 constexpr int (S::*pf)() const = &S::f;
842 constexpr int (S::*pg)() const = &S::g;
843
844 constexpr S s(2, 5, &S::f, &S::m);
845
Richard Smith9eed49c2011-12-09 23:00:37 +0000846 static_assert((s.*&S::f)() == 2, "");
847 static_assert((s.*s.pf)() == 2, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000848
Richard Smithb02e4622012-02-01 01:42:44 +0000849 static_assert(pf == &S::f, "");
850 static_assert(pf == s.*&S::pf, "");
851 static_assert(pm == &S::m, "");
852 static_assert(pm != pn, "");
853 static_assert(s.pn != pn, "");
854 static_assert(s.pn == pm, "");
855 static_assert(pg != nullptr, "");
856 static_assert(pf != nullptr, "");
857 static_assert((int S::*)nullptr == nullptr, "");
858 static_assert(pg == pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}}
859 static_assert(pf != pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}}
860
Richard Smithe24f5fc2011-11-17 22:56:20 +0000861 template<int n> struct T : T<n-1> {};
862 template<> struct T<0> { int n; };
863 template<> struct T<30> : T<29> { int m; };
864
865 T<17> t17;
866 T<30> t30;
867
868 constexpr int (T<10>::*deepn) = &T<0>::n;
Richard Smith9eed49c2011-12-09 23:00:37 +0000869 static_assert(&(t17.*deepn) == &t17.n, "");
Richard Smithb02e4622012-02-01 01:42:44 +0000870 static_assert(deepn == &T<2>::n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000871
872 constexpr int (T<15>::*deepm) = (int(T<10>::*))&T<30>::m;
873 constexpr int *pbad = &(t17.*deepm); // expected-error {{constant expression}}
Richard Smith9eed49c2011-12-09 23:00:37 +0000874 static_assert(&(t30.*deepm) == &t30.m, "");
Richard Smithb02e4622012-02-01 01:42:44 +0000875 static_assert(deepm == &T<50>::m, "");
876 static_assert(deepm != deepn, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000877
878 constexpr T<5> *p17_5 = &t17;
879 constexpr T<13> *p17_13 = (T<13>*)p17_5;
Richard Smithb4e85ed2012-01-06 16:39:00 +0000880 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 +0000881 static_assert(&(p17_5->*(int(T<3>::*))deepn) == &t17.n, "");
882 static_assert(&(p17_13->*deepn) == &t17.n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000883 constexpr int *pbad2 = &(p17_13->*(int(T<9>::*))deepm); // expected-error {{constant expression}}
884
885 constexpr T<5> *p30_5 = &t30;
886 constexpr T<23> *p30_23 = (T<23>*)p30_5;
887 constexpr T<13> *p30_13 = p30_23;
Richard Smith9eed49c2011-12-09 23:00:37 +0000888 static_assert(&(p30_5->*(int(T<3>::*))deepn) == &t30.n, "");
889 static_assert(&(p30_13->*deepn) == &t30.n, "");
890 static_assert(&(p30_23->*deepn) == &t30.n, "");
891 static_assert(&(p30_5->*(int(T<2>::*))deepm) == &t30.m, "");
892 static_assert(&(((T<17>*)p30_13)->*deepm) == &t30.m, "");
893 static_assert(&(p30_23->*deepm) == &t30.m, "");
Richard Smithb02e4622012-02-01 01:42:44 +0000894
895 struct Base { int n; };
896 template<int N> struct Mid : Base {};
897 struct Derived : Mid<0>, Mid<1> {};
898 static_assert(&Mid<0>::n == &Mid<1>::n, "");
899 static_assert((int Derived::*)(int Mid<0>::*)&Mid<0>::n !=
900 (int Derived::*)(int Mid<1>::*)&Mid<1>::n, "");
901 static_assert(&Mid<0>::n == (int Mid<0>::*)&Base::n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000902}
903
904namespace ArrayBaseDerived {
905
906 struct Base {
907 constexpr Base() {}
908 int n = 0;
909 };
910 struct Derived : Base {
911 constexpr Derived() {}
912 constexpr const int *f() { return &n; }
913 };
914
915 constexpr Derived a[10];
916 constexpr Derived *pd3 = const_cast<Derived*>(&a[3]);
917 constexpr Base *pb3 = const_cast<Derived*>(&a[3]);
Richard Smith9eed49c2011-12-09 23:00:37 +0000918 static_assert(pb3 == pd3, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000919
920 // pb3 does not point to an array element.
921 constexpr Base *pb4 = pb3 + 1; // ok, one-past-the-end pointer.
Richard Smithb4e85ed2012-01-06 16:39:00 +0000922 constexpr int pb4n = pb4->n; // expected-error {{constant expression}} expected-note {{cannot access field of pointer past the end}}
923 constexpr Base *err_pb5 = pb3 + 2; // expected-error {{constant expression}} expected-note {{cannot refer to element 2}} expected-note {{here}}
924 constexpr int err_pb5n = err_pb5->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb5' is not a constant expression}}
925 constexpr Base *err_pb2 = pb3 - 1; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} expected-note {{here}}
926 constexpr int err_pb2n = err_pb2->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb2'}}
Richard Smithe24f5fc2011-11-17 22:56:20 +0000927 constexpr Base *pb3a = pb4 - 1;
928
929 // pb4 does not point to a Derived.
Richard Smithb4e85ed2012-01-06 16:39:00 +0000930 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 +0000931 constexpr Derived *pd3a = (Derived*)pb3a;
932 constexpr int pd3n = pd3a->n;
933
934 // pd3a still points to the Derived array.
935 constexpr Derived *pd6 = pd3a + 3;
Richard Smith9eed49c2011-12-09 23:00:37 +0000936 static_assert(pd6 == &a[6], "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000937 constexpr Derived *pd9 = pd6 + 3;
938 constexpr Derived *pd10 = pd6 + 4;
939 constexpr int pd9n = pd9->n; // ok
Richard Smithb4e85ed2012-01-06 16:39:00 +0000940 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 +0000941 constexpr int pd0n = pd10[-10].n;
Richard Smithb4e85ed2012-01-06 16:39:00 +0000942 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 +0000943
944 constexpr Base *pb9 = pd9;
945 constexpr const int *(Base::*pfb)() const =
946 static_cast<const int *(Base::*)() const>(&Derived::f);
Richard Smith9eed49c2011-12-09 23:00:37 +0000947 static_assert((pb9->*pfb)() == &a[9].n, "");
Richard Smithe24f5fc2011-11-17 22:56:20 +0000948}
949
Richard Smith59efe262011-11-11 04:05:33 +0000950namespace Complex {
951
952class complex {
953 int re, im;
954public:
955 constexpr complex(int re = 0, int im = 0) : re(re), im(im) {}
956 constexpr complex(const complex &o) : re(o.re), im(o.im) {}
957 constexpr complex operator-() const { return complex(-re, -im); }
958 friend constexpr complex operator+(const complex &l, const complex &r) {
959 return complex(l.re + r.re, l.im + r.im);
960 }
961 friend constexpr complex operator-(const complex &l, const complex &r) {
962 return l + -r;
963 }
964 friend constexpr complex operator*(const complex &l, const complex &r) {
965 return complex(l.re * r.re - l.im * r.im, l.re * r.im + l.im * r.re);
966 }
967 friend constexpr bool operator==(const complex &l, const complex &r) {
968 return l.re == r.re && l.im == r.im;
969 }
970 constexpr bool operator!=(const complex &r) const {
971 return re != r.re || im != r.im;
972 }
973 constexpr int real() const { return re; }
974 constexpr int imag() const { return im; }
975};
976
977constexpr complex i = complex(0, 1);
978constexpr complex k = (3 + 4*i) * (6 - 4*i);
Richard Smith9eed49c2011-12-09 23:00:37 +0000979static_assert(complex(1,0).real() == 1, "");
980static_assert(complex(1,0).imag() == 0, "");
981static_assert(((complex)1).imag() == 0, "");
982static_assert(k.real() == 34, "");
983static_assert(k.imag() == 12, "");
984static_assert(k - 34 == 12*i, "");
985static_assert((complex)1 == complex(1), "");
986static_assert((complex)1 != complex(0, 1), "");
987static_assert(complex(1) == complex(1), "");
988static_assert(complex(1) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +0000989constexpr complex makeComplex(int re, int im) { return complex(re, im); }
Richard Smith9eed49c2011-12-09 23:00:37 +0000990static_assert(makeComplex(1,0) == complex(1), "");
991static_assert(makeComplex(1,0) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +0000992
993class complex_wrap : public complex {
994public:
995 constexpr complex_wrap(int re, int im = 0) : complex(re, im) {}
996 constexpr complex_wrap(const complex_wrap &o) : complex(o) {}
997};
998
Richard Smith9eed49c2011-12-09 23:00:37 +0000999static_assert((complex_wrap)1 == complex(1), "");
1000static_assert((complex)1 != complex_wrap(0, 1), "");
1001static_assert(complex(1) == complex_wrap(1), "");
1002static_assert(complex_wrap(1) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001003constexpr complex_wrap makeComplexWrap(int re, int im) {
1004 return complex_wrap(re, im);
1005}
Richard Smith9eed49c2011-12-09 23:00:37 +00001006static_assert(makeComplexWrap(1,0) == complex(1), "");
1007static_assert(makeComplexWrap(1,0) != complex(0, 1), "");
Richard Smith59efe262011-11-11 04:05:33 +00001008
1009}
Eli Friedmanf59ff8c2011-12-17 02:24:21 +00001010
1011namespace PR11595 {
1012 struct A { constexpr bool operator==(int x) { return true; } };
Richard Smithaf2c7a12011-12-19 22:01:37 +00001013 struct B { B(); A& x; };
1014 static_assert(B().x == 3, ""); // expected-error {{constant expression}} expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
1015
Richard Smith745f5142012-01-27 01:14:48 +00001016 constexpr bool f(int k) { // expected-error {{constexpr function never produces a constant expression}}
Richard Smithaf2c7a12011-12-19 22:01:37 +00001017 return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
1018 }
Eli Friedmanf59ff8c2011-12-17 02:24:21 +00001019}
Richard Smithbc6abe92011-12-19 22:12:41 +00001020
1021namespace ExprWithCleanups {
1022 struct A { A(); ~A(); int get(); };
1023 constexpr int get(bool FromA) { return FromA ? A().get() : 1; }
1024 constexpr int n = get(false);
1025}
Richard Smith7098cbd2011-12-21 05:04:46 +00001026
1027namespace Volatile {
1028
1029volatile constexpr int n1 = 0; // expected-note {{here}}
1030volatile const int n2 = 0; // expected-note {{here}}
1031int n3 = 37; // expected-note {{declared here}}
1032
Richard Smith9ec71972012-02-05 01:23:16 +00001033constexpr int m1 = n1; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
1034constexpr int m2 = n2; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
1035constexpr int m1b = const_cast<const int&>(n1); // expected-error {{constant expression}} expected-note {{read of volatile object 'n1'}}
1036constexpr 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 +00001037
1038struct T { int n; };
1039const T t = { 42 }; // expected-note {{declared here}}
1040
1041constexpr int f(volatile int &&r) {
Richard Smith9ec71972012-02-05 01:23:16 +00001042 return r; // expected-note {{read of volatile-qualified type 'volatile int'}}
1043}
1044constexpr int g(volatile int &&r) {
1045 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 +00001046}
1047struct S {
Richard Smith9ec71972012-02-05 01:23:16 +00001048 int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}}
1049 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 +00001050 int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}}
1051 int m : t.n; // expected-error {{constant expression}} expected-note {{read of non-constexpr variable}}
1052};
1053
1054}
Richard Smithdd4b3502011-12-25 21:17:58 +00001055
1056namespace ExternConstexpr {
1057 extern constexpr int n = 0;
1058 extern constexpr int m; // expected-error {{constexpr variable declaration must be a definition}}
1059 void f() {
1060 extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}}
1061 constexpr int j = 0;
1062 constexpr int k; // expected-error {{default initialization of an object of const type}}
1063 }
1064}
Eli Friedman7ead5c72012-01-10 04:58:17 +00001065
1066namespace ComplexConstexpr {
1067 constexpr _Complex float test1 = {};
1068 constexpr _Complex float test2 = {1};
1069 constexpr _Complex double test3 = {1,2};
1070 constexpr _Complex int test4 = {4};
1071 constexpr _Complex int test5 = 4;
1072 constexpr _Complex int test6 = {5,6};
Eli Friedmanf6c17a42012-01-13 23:34:56 +00001073 typedef _Complex float fcomplex;
1074 constexpr fcomplex test7 = fcomplex();
Richard Smith86024012012-02-18 22:04:06 +00001075
1076 constexpr const double &t2r = __real test3;
1077 constexpr const double &t2i = __imag test3;
1078 static_assert(&t2r + 1 == &t2i, "");
1079 static_assert(t2r == 1.0, "");
1080 static_assert(t2i == 2.0, "");
1081 constexpr const double *t2p = &t2r;
1082 static_assert(t2p[-1] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element -1 of array of 2 elements}}
1083 static_assert(t2p[0] == 1.0, "");
1084 static_assert(t2p[1] == 2.0, "");
1085 static_assert(t2p[2] == 0.0, ""); // expected-error {{constant expr}} expected-note {{one-past-the-end pointer}}
1086 static_assert(t2p[3] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element 3 of array of 2 elements}}
1087 constexpr _Complex float *p = 0;
1088 constexpr float pr = __real *p; // expected-error {{constant expr}} expected-note {{cannot access real component of null}}
1089 constexpr float pi = __imag *p; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of null}}
1090 constexpr const _Complex double *q = &test3 + 1;
1091 constexpr double qr = __real *q; // expected-error {{constant expr}} expected-note {{cannot access real component of pointer past the end}}
1092 constexpr double qi = __imag *q; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of pointer past the end}}
1093
1094 static_assert(__real test6 == 5, "");
1095 static_assert(__imag test6 == 6, "");
1096 static_assert(&__imag test6 == &__real test6 + 1, "");
Eli Friedman7ead5c72012-01-10 04:58:17 +00001097}
Eli Friedman6b3014b2012-01-18 02:54:10 +00001098
1099namespace InstantiateCaseStmt {
1100 template<int x> constexpr int f() { return x; }
1101 template<int x> int g(int c) { switch(c) { case f<x>(): return 1; } return 0; }
1102 int gg(int c) { return g<4>(c); }
1103}
Richard Smith495f42a2012-01-24 05:40:50 +00001104
1105namespace ConvertedConstantExpr {
1106 extern int &m;
1107 extern int &n;
1108
1109 constexpr int k = 4;
1110 int &m = const_cast<int&>(k);
1111
1112 // If we have nothing more interesting to say, ensure we don't produce a
1113 // useless note and instead just point to the non-constant subexpression.
1114 enum class E {
1115 em = m,
1116 en = n, // expected-error {{not a constant expression}}
1117 eo = (m +
1118 n // expected-error {{not a constant expression}}
1119 ),
1120 eq = reinterpret_cast<int>((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}}
1121 };
1122}
Richard Smithd9b02e72012-01-25 22:15:11 +00001123
1124namespace IndirectField {
1125 struct S {
1126 struct { // expected-warning {{GNU extension}}
1127 union {
1128 struct { // expected-warning {{GNU extension}}
1129 int a;
1130 int b;
1131 };
1132 int c;
1133 };
1134 int d;
1135 };
1136 union {
1137 int e;
1138 int f;
1139 };
1140 constexpr S(int a, int b, int d, int e) : a(a), b(b), d(d), e(e) {}
1141 constexpr S(int c, int d, int f) : c(c), d(d), f(f) {}
1142 };
1143
1144 constexpr S s1(1, 2, 3, 4);
1145 constexpr S s2(5, 6, 7);
1146
1147 // FIXME: The diagnostics here do a very poor job of explaining which unnamed
1148 // member is active and which is requested.
1149 static_assert(s1.a == 1, "");
1150 static_assert(s1.b == 2, "");
1151 static_assert(s1.c == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1152 static_assert(s1.d == 3, "");
1153 static_assert(s1.e == 4, "");
1154 static_assert(s1.f == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1155
1156 static_assert(s2.a == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1157 static_assert(s2.b == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1158 static_assert(s2.c == 5, "");
1159 static_assert(s2.d == 6, "");
1160 static_assert(s2.e == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1161 static_assert(s2.f == 7, "");
1162}
Richard Smithf15fda02012-02-02 01:16:57 +00001163
Richard Smithb4e5e282012-02-09 03:29:58 +00001164// DR1405: don't allow reading mutable members in constant expressions.
1165namespace MutableMembers {
1166 struct MM {
1167 mutable int n; // expected-note 3{{declared here}}
1168 } constexpr mm = { 4 };
1169 constexpr int mmn = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
1170 int x = (mm.n = 1, 3);
1171 constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
1172
1173 // Here's one reason why allowing this would be a disaster...
1174 template<int n> struct Id { int k = n; };
1175 int f() {
1176 constexpr MM m = { 0 };
1177 ++m.n;
1178 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}}
1179 }
1180
1181 struct A { int n; };
1182 struct B { mutable A a; }; // expected-note {{here}}
1183 struct C { B b; };
1184 constexpr C c[3] = {};
1185 constexpr int k = c[1].b.a.n; // expected-error {{constant expression}} expected-note {{mutable}}
1186}
1187
Richard Smithf15fda02012-02-02 01:16:57 +00001188namespace Fold {
1189
1190 // This macro forces its argument to be constant-folded, even if it's not
1191 // otherwise a constant expression.
1192 #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
1193
1194 constexpr int n = (int)(char*)123; // expected-error {{constant expression}} expected-note {{reinterpret_cast}}
1195 constexpr int m = fold((int)(char*)123); // ok
1196 static_assert(m == 123, "");
1197
1198 #undef fold
1199
1200}
Richard Smith83587db2012-02-15 02:18:13 +00001201
1202namespace DR1454 {
1203
1204constexpr const int &f(const int &n) { return n; }
1205constexpr int k1 = f(0); // ok
1206
1207struct Wrap {
1208 const int &value;
1209};
1210constexpr const Wrap &g(const Wrap &w) { return w; }
1211constexpr int k2 = g({0}).value; // ok
1212
1213constexpr const int &i = 0; // expected-error {{constant expression}} expected-note {{temporary}} expected-note 2{{here}}
1214constexpr const int j = i; // expected-error {{constant expression}} expected-note {{initializer of 'i' is not a constant expression}}
1215
1216}
Richard Smith74e1ad92012-02-16 02:46:34 +00001217
1218namespace RecursiveOpaqueExpr {
1219 template<typename Iter>
1220 constexpr auto LastNonzero(Iter p, Iter q) -> decltype(+*p) {
1221 return p != q ? (LastNonzero(p+1, q) ?: *p) : 0; // expected-warning {{GNU}}
1222 }
1223
1224 constexpr int arr1[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 0 };
1225 static_assert(LastNonzero(begin(arr1), end(arr1)) == 4, "");
1226
1227 constexpr int arr2[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 5 };
1228 static_assert(LastNonzero(begin(arr2), end(arr2)) == 5, "");
Richard Smithe92b1f42012-06-26 08:12:11 +00001229
1230 constexpr int arr3[] = {
1231 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,
1232 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,
1233 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,
1234 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,
1235 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,
1236 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,
1237 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,
1238 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 };
1239 static_assert(LastNonzero(begin(arr3), end(arr3)) == 2, "");
Richard Smith74e1ad92012-02-16 02:46:34 +00001240}
1241
1242namespace VLASizeof {
1243
1244 void f(int k) {
1245 int arr[k]; // expected-warning {{C99}}
1246 constexpr int n = 1 +
1247 sizeof(arr) // expected-error {{constant expression}}
1248 * 3;
1249 }
1250}
Richard Smithb78ae972012-02-18 04:58:18 +00001251
1252namespace CompoundLiteral {
1253 // FIXME:
1254 // We don't model the semantics of this correctly: the compound literal is
1255 // represented as a prvalue in the AST, but actually behaves like an lvalue.
1256 // We treat the compound literal as a temporary and refuse to produce a
1257 // pointer to it. This is OK: we're not required to treat this as a constant
1258 // in C++, and in C we model compound literals as lvalues.
1259 constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}}
1260}
Richard Smith4b1f6842012-03-13 20:58:32 +00001261
1262namespace Vector {
1263 typedef int __attribute__((vector_size(16))) VI4;
1264 constexpr VI4 f(int n) {
1265 return VI4 { n * 3, n + 4, n - 5, n / 6 };
1266 }
1267 constexpr auto v1 = f(10);
1268
1269 typedef double __attribute__((vector_size(32))) VD4;
1270 constexpr VD4 g(int n) {
1271 return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 }; // expected-warning {{C99}}
1272 }
1273 constexpr auto v2 = g(4);
1274}
John McCall8d59dee2012-05-01 00:38:49 +00001275
1276// PR12626, redux
1277namespace InvalidClasses {
1278 void test0() {
1279 struct X; // expected-note {{forward declaration}}
1280 struct Y { bool b; X x; }; // expected-error {{field has incomplete type}}
1281 Y y;
1282 auto& b = y.b;
1283 }
1284}
Richard Smithdbbeccc2012-05-15 05:04:02 +00001285
Richard Smith622da852012-07-02 06:15:40 +00001286// Constructors can be implicitly constexpr, even for a non-literal type.
1287namespace ImplicitConstexpr {
1288 struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}}
1289 struct R { constexpr R(); constexpr R(const R&); constexpr R(R&&); ~R(); };
1290 struct S { R r; }; // expected-note 3{{here}}
1291 struct T { T(const T&); T(T &&); ~T(); };
1292 struct U { T t; }; // expected-note 3{{here}}
1293 static_assert(!__is_literal_type(Q), "");
1294 static_assert(!__is_literal_type(R), "");
1295 static_assert(!__is_literal_type(S), "");
1296 static_assert(!__is_literal_type(T), "");
1297 static_assert(!__is_literal_type(U), "");
1298 struct Test {
1299 friend Q::Q() noexcept; // expected-error {{follows constexpr}}
1300 friend Q::Q(Q&&) noexcept; // expected-error {{follows constexpr}}
1301 friend Q::Q(const Q&) noexcept; // expected-error {{follows constexpr}}
1302 friend S::S() noexcept; // expected-error {{follows constexpr}}
1303 friend S::S(S&&) noexcept; // expected-error {{follows constexpr}}
1304 friend S::S(const S&) noexcept; // expected-error {{follows constexpr}}
1305 friend constexpr U::U() noexcept; // expected-error {{follows non-constexpr}}
1306 friend constexpr U::U(U&&) noexcept; // expected-error {{follows non-constexpr}}
1307 friend constexpr U::U(const U&) noexcept; // expected-error {{follows non-constexpr}}
1308 };
1309}
1310
Richard Smithdbbeccc2012-05-15 05:04:02 +00001311// Indirectly test that an implicit lvalue to xvalue conversion performed for
1312// an NRVO move operation isn't implemented as CK_LValueToRValue.
1313namespace PR12826 {
1314 struct Foo {};
1315 constexpr Foo id(Foo x) { return x; }
1316 constexpr Foo res(id(Foo()));
1317}
Richard Smithf4bb8d02012-07-05 08:39:21 +00001318
1319namespace PR13273 {
1320 struct U {
1321 int t;
1322 U() = default;
1323 };
1324
1325 struct S : U {
1326 S() = default;
1327 };
1328
1329 // S's default constructor isn't constexpr, because U's default constructor
1330 // doesn't initialize 't', but it's trivial, so value-initialization doesn't
1331 // actually call it.
1332 static_assert(S{}.t == 0, "");
1333}
Richard Smith20599392012-07-07 08:35:56 +00001334
1335namespace PR12670 {
1336 struct S {
1337 constexpr S(int a0) : m(a0) {}
1338 constexpr S() : m(6) {}
1339 int m;
1340 };
1341 constexpr S x[3] = { {4}, 5 };
1342 static_assert(x[0].m == 4, "");
1343 static_assert(x[1].m == 5, "");
1344 static_assert(x[2].m == 6, "");
1345}