xref: /minix3/external/bsd/llvm/dist/clang/test/SemaCXX/constant-expression-cxx11.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc namespace StaticAssertFoldTest {
4f4a2713aSLionel Sambuc 
5f4a2713aSLionel Sambuc int x;
6f4a2713aSLionel Sambuc static_assert(++x, "test"); // expected-error {{not an integral constant expression}}
7f4a2713aSLionel Sambuc static_assert(false, "test"); // expected-error {{test}}
8f4a2713aSLionel Sambuc 
9f4a2713aSLionel Sambuc }
10f4a2713aSLionel Sambuc 
11f4a2713aSLionel Sambuc typedef decltype(sizeof(char)) size_t;
12f4a2713aSLionel Sambuc 
id(const T & t)13f4a2713aSLionel Sambuc template<typename T> constexpr T id(const T &t) { return t; }
min(const T & a,const T & b)14f4a2713aSLionel Sambuc template<typename T> constexpr T min(const T &a, const T &b) {
15f4a2713aSLionel Sambuc   return a < b ? a : b;
16f4a2713aSLionel Sambuc }
max(const T & a,const T & b)17f4a2713aSLionel Sambuc template<typename T> constexpr T max(const T &a, const T &b) {
18f4a2713aSLionel Sambuc   return a < b ? b : a;
19f4a2713aSLionel Sambuc }
begin(T (& xs)[N])20f4a2713aSLionel Sambuc template<typename T, size_t N> constexpr T *begin(T (&xs)[N]) { return xs; }
end(T (& xs)[N])21f4a2713aSLionel Sambuc template<typename T, size_t N> constexpr T *end(T (&xs)[N]) { return xs + N; }
22f4a2713aSLionel Sambuc 
23f4a2713aSLionel Sambuc struct MemberZero {
zeroMemberZero24f4a2713aSLionel Sambuc   constexpr int zero() const { return 0; }
25f4a2713aSLionel Sambuc };
26f4a2713aSLionel Sambuc 
27f4a2713aSLionel Sambuc namespace DerivedToVBaseCast {
28f4a2713aSLionel Sambuc 
29f4a2713aSLionel Sambuc   struct U { int n; };
30f4a2713aSLionel Sambuc   struct V : U { int n; };
31f4a2713aSLionel Sambuc   struct A : virtual V { int n; };
32f4a2713aSLionel Sambuc   struct Aa { int n; };
33f4a2713aSLionel Sambuc   struct B : virtual A, Aa {};
34f4a2713aSLionel Sambuc   struct C : virtual A, Aa {};
35f4a2713aSLionel Sambuc   struct D : B, C {};
36f4a2713aSLionel Sambuc 
37f4a2713aSLionel Sambuc   D d;
38f4a2713aSLionel Sambuc   constexpr B *p = &d;
39f4a2713aSLionel Sambuc   constexpr C *q = &d;
40f4a2713aSLionel Sambuc 
41f4a2713aSLionel Sambuc   static_assert((void*)p != (void*)q, "");
42f4a2713aSLionel Sambuc   static_assert((A*)p == (A*)q, "");
43f4a2713aSLionel Sambuc   static_assert((Aa*)p != (Aa*)q, "");
44f4a2713aSLionel Sambuc 
45f4a2713aSLionel Sambuc   constexpr B &pp = d;
46f4a2713aSLionel Sambuc   constexpr C &qq = d;
47f4a2713aSLionel Sambuc   static_assert((void*)&pp != (void*)&qq, "");
48f4a2713aSLionel Sambuc   static_assert(&(A&)pp == &(A&)qq, "");
49f4a2713aSLionel Sambuc   static_assert(&(Aa&)pp != &(Aa&)qq, "");
50f4a2713aSLionel Sambuc 
51f4a2713aSLionel Sambuc   constexpr V *v = p;
52f4a2713aSLionel Sambuc   constexpr V *w = q;
53f4a2713aSLionel Sambuc   constexpr V *x = (A*)p;
54f4a2713aSLionel Sambuc   static_assert(v == w, "");
55f4a2713aSLionel Sambuc   static_assert(v == x, "");
56f4a2713aSLionel Sambuc 
57f4a2713aSLionel Sambuc   static_assert((U*)&d == p, "");
58f4a2713aSLionel Sambuc   static_assert((U*)&d == q, "");
59f4a2713aSLionel Sambuc   static_assert((U*)&d == v, "");
60f4a2713aSLionel Sambuc   static_assert((U*)&d == w, "");
61f4a2713aSLionel Sambuc   static_assert((U*)&d == x, "");
62f4a2713aSLionel Sambuc 
63f4a2713aSLionel Sambuc   struct X {};
64f4a2713aSLionel Sambuc   struct Y1 : virtual X {};
65f4a2713aSLionel Sambuc   struct Y2 : X {};
66f4a2713aSLionel Sambuc   struct Z : Y1, Y2 {};
67f4a2713aSLionel Sambuc   Z z;
68f4a2713aSLionel Sambuc   static_assert((X*)(Y1*)&z != (X*)(Y2*)&z, "");
69f4a2713aSLionel Sambuc }
70f4a2713aSLionel Sambuc 
71f4a2713aSLionel Sambuc namespace ConstCast {
72f4a2713aSLionel Sambuc 
73f4a2713aSLionel Sambuc constexpr int n1 = 0;
74f4a2713aSLionel Sambuc constexpr int n2 = const_cast<int&>(n1);
75f4a2713aSLionel Sambuc constexpr int *n3 = const_cast<int*>(&n1);
76f4a2713aSLionel Sambuc constexpr int n4 = *const_cast<int*>(&n1);
77f4a2713aSLionel Sambuc constexpr const int * const *n5 = const_cast<const int* const*>(&n3);
78f4a2713aSLionel Sambuc constexpr int **n6 = const_cast<int**>(&n3);
79f4a2713aSLionel Sambuc constexpr int n7 = **n5;
80f4a2713aSLionel Sambuc constexpr int n8 = **n6;
81f4a2713aSLionel Sambuc 
82f4a2713aSLionel Sambuc // const_cast from prvalue to xvalue.
83f4a2713aSLionel Sambuc struct A { int n; };
84f4a2713aSLionel Sambuc constexpr int n9 = (const_cast<A&&>(A{123})).n;
85f4a2713aSLionel Sambuc static_assert(n9 == 123, "");
86f4a2713aSLionel Sambuc 
87f4a2713aSLionel Sambuc }
88f4a2713aSLionel Sambuc 
89f4a2713aSLionel Sambuc namespace TemplateArgumentConversion {
90f4a2713aSLionel Sambuc   template<int n> struct IntParam {};
91f4a2713aSLionel Sambuc 
92f4a2713aSLionel Sambuc   using IntParam0 = IntParam<0>;
93f4a2713aSLionel Sambuc   using IntParam0 = IntParam<id(0)>;
94f4a2713aSLionel Sambuc   using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}}
95f4a2713aSLionel Sambuc }
96f4a2713aSLionel Sambuc 
97f4a2713aSLionel Sambuc namespace CaseStatements {
98*0a6a1f1dSLionel Sambuc   int x;
f(int n)99f4a2713aSLionel Sambuc   void f(int n) {
100f4a2713aSLionel Sambuc     switch (n) {
101f4a2713aSLionel Sambuc     case MemberZero().zero: // expected-error {{did you mean to call it with no arguments?}} expected-note {{previous}}
102f4a2713aSLionel Sambuc     case id(0): // expected-error {{duplicate case value '0'}}
103f4a2713aSLionel Sambuc       return;
104*0a6a1f1dSLionel Sambuc     case __builtin_constant_p(true) ? (__SIZE_TYPE__)&x : 0:; // expected-error {{constant}}
105f4a2713aSLionel Sambuc     }
106f4a2713aSLionel Sambuc   }
107f4a2713aSLionel Sambuc }
108f4a2713aSLionel Sambuc 
109f4a2713aSLionel Sambuc extern int &Recurse1;
110f4a2713aSLionel Sambuc int &Recurse2 = Recurse1; // expected-note {{declared here}}
111f4a2713aSLionel Sambuc int &Recurse1 = Recurse2;
112f4a2713aSLionel Sambuc constexpr int &Recurse3 = Recurse2; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'Recurse2' is not a constant expression}}
113f4a2713aSLionel Sambuc 
114f4a2713aSLionel Sambuc extern const int RecurseA;
115f4a2713aSLionel Sambuc const int RecurseB = RecurseA; // expected-note {{declared here}}
116f4a2713aSLionel Sambuc const int RecurseA = 10;
117f4a2713aSLionel Sambuc constexpr int RecurseC = RecurseB; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'RecurseB' is not a constant expression}}
118f4a2713aSLionel Sambuc 
119f4a2713aSLionel Sambuc namespace MemberEnum {
120f4a2713aSLionel Sambuc   struct WithMemberEnum {
121f4a2713aSLionel Sambuc     enum E { A = 42 };
122f4a2713aSLionel Sambuc   } wme;
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc   static_assert(wme.A == 42, "");
125f4a2713aSLionel Sambuc }
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc namespace DefaultArguments {
128f4a2713aSLionel Sambuc 
129f4a2713aSLionel Sambuc const int z = int();
Sum(int a=0,const int & b=0,const int * c=& z,char d=0)130f4a2713aSLionel Sambuc constexpr int Sum(int a = 0, const int &b = 0, const int *c = &z, char d = 0) {
131f4a2713aSLionel Sambuc   return a + b + *c + d;
132f4a2713aSLionel Sambuc }
133f4a2713aSLionel Sambuc const int four = 4;
134f4a2713aSLionel Sambuc constexpr int eight = 8;
135f4a2713aSLionel Sambuc constexpr const int twentyseven = 27;
136f4a2713aSLionel Sambuc static_assert(Sum() == 0, "");
137f4a2713aSLionel Sambuc static_assert(Sum(1) == 1, "");
138f4a2713aSLionel Sambuc static_assert(Sum(1, four) == 5, "");
139f4a2713aSLionel Sambuc static_assert(Sum(1, eight, &twentyseven) == 36, "");
140f4a2713aSLionel Sambuc static_assert(Sum(1, 2, &four, eight) == 15, "");
141f4a2713aSLionel Sambuc 
142f4a2713aSLionel Sambuc }
143f4a2713aSLionel Sambuc 
144f4a2713aSLionel Sambuc namespace Ellipsis {
145f4a2713aSLionel Sambuc 
146f4a2713aSLionel Sambuc // Note, values passed through an ellipsis can't actually be used.
F(int a,...)147f4a2713aSLionel Sambuc constexpr int F(int a, ...) { return a; }
148f4a2713aSLionel Sambuc static_assert(F(0) == 0, "");
149f4a2713aSLionel Sambuc static_assert(F(1, 0) == 1, "");
150f4a2713aSLionel Sambuc static_assert(F(2, "test") == 2, "");
151f4a2713aSLionel Sambuc static_assert(F(3, &F) == 3, "");
152f4a2713aSLionel Sambuc int k = 0; // expected-note {{here}}
153f4a2713aSLionel Sambuc static_assert(F(4, k) == 3, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'k'}}
154f4a2713aSLionel Sambuc 
155f4a2713aSLionel Sambuc }
156f4a2713aSLionel Sambuc 
157f4a2713aSLionel Sambuc namespace Recursion {
fib(int n)158f4a2713aSLionel Sambuc   constexpr int fib(int n) { return n > 1 ? fib(n-1) + fib(n-2) : n; }
159f4a2713aSLionel Sambuc   static_assert(fib(11) == 89, "");
160f4a2713aSLionel Sambuc 
gcd_inner(int a,int b)161f4a2713aSLionel Sambuc   constexpr int gcd_inner(int a, int b) {
162f4a2713aSLionel Sambuc     return b == 0 ? a : gcd_inner(b, a % b);
163f4a2713aSLionel Sambuc   }
gcd(int a,int b)164f4a2713aSLionel Sambuc   constexpr int gcd(int a, int b) {
165f4a2713aSLionel Sambuc     return gcd_inner(max(a, b), min(a, b));
166f4a2713aSLionel Sambuc   }
167f4a2713aSLionel Sambuc 
168f4a2713aSLionel Sambuc   static_assert(gcd(1749237, 5628959) == 7, "");
169f4a2713aSLionel Sambuc }
170f4a2713aSLionel Sambuc 
171f4a2713aSLionel Sambuc namespace FunctionCast {
172f4a2713aSLionel Sambuc   // When folding, we allow functions to be cast to different types. Such
173f4a2713aSLionel Sambuc   // cast functions cannot be called, even if they're constexpr.
f()174f4a2713aSLionel Sambuc   constexpr int f() { return 1; }
175f4a2713aSLionel Sambuc   typedef double (*DoubleFn)();
176f4a2713aSLionel Sambuc   typedef int (*IntFn)();
177f4a2713aSLionel Sambuc   int a[(int)DoubleFn(f)()]; // expected-error {{variable length array}} expected-warning{{C99 feature}}
178f4a2713aSLionel Sambuc   int b[(int)IntFn(f)()];    // ok
179f4a2713aSLionel Sambuc }
180f4a2713aSLionel Sambuc 
181f4a2713aSLionel Sambuc namespace StaticMemberFunction {
182f4a2713aSLionel Sambuc   struct S {
183f4a2713aSLionel Sambuc     static constexpr int k = 42;
fStaticMemberFunction::S184f4a2713aSLionel Sambuc     static constexpr int f(int n) { return n * k + 2; }
185f4a2713aSLionel Sambuc   } s;
186f4a2713aSLionel Sambuc 
187f4a2713aSLionel Sambuc   constexpr int n = s.f(19);
188f4a2713aSLionel Sambuc   static_assert(S::f(19) == 800, "");
189f4a2713aSLionel Sambuc   static_assert(s.f(19) == 800, "");
190f4a2713aSLionel Sambuc   static_assert(n == 800, "");
191f4a2713aSLionel Sambuc 
192f4a2713aSLionel Sambuc   constexpr int (*sf1)(int) = &S::f;
193f4a2713aSLionel Sambuc   constexpr int (*sf2)(int) = &s.f;
194f4a2713aSLionel Sambuc   constexpr const int *sk = &s.k;
195f4a2713aSLionel Sambuc }
196f4a2713aSLionel Sambuc 
197f4a2713aSLionel Sambuc namespace ParameterScopes {
198f4a2713aSLionel Sambuc 
199f4a2713aSLionel Sambuc   const int k = 42;
ObscureTheTruth(const int & a)200f4a2713aSLionel Sambuc   constexpr const int &ObscureTheTruth(const int &a) { return a; }
MaybeReturnJunk(bool b,const int a)201f4a2713aSLionel Sambuc   constexpr const int &MaybeReturnJunk(bool b, const int a) { // expected-note 2{{declared here}}
202f4a2713aSLionel Sambuc     return ObscureTheTruth(b ? a : k);
203f4a2713aSLionel Sambuc   }
204f4a2713aSLionel Sambuc   static_assert(MaybeReturnJunk(false, 0) == 42, ""); // ok
205f4a2713aSLionel Sambuc   constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}} expected-note {{read of variable whose lifetime has ended}}
206f4a2713aSLionel Sambuc 
MaybeReturnNonstaticRef(bool b,const int a)207f4a2713aSLionel Sambuc   constexpr const int MaybeReturnNonstaticRef(bool b, const int a) {
208f4a2713aSLionel Sambuc     return ObscureTheTruth(b ? a : k);
209f4a2713aSLionel Sambuc   }
210f4a2713aSLionel Sambuc   static_assert(MaybeReturnNonstaticRef(false, 0) == 42, ""); // ok
211f4a2713aSLionel Sambuc   constexpr int b = MaybeReturnNonstaticRef(true, 0); // ok
212f4a2713aSLionel Sambuc 
InternalReturnJunk(int n)213f4a2713aSLionel Sambuc   constexpr int InternalReturnJunk(int n) {
214f4a2713aSLionel Sambuc     return MaybeReturnJunk(true, n); // expected-note {{read of variable whose lifetime has ended}}
215f4a2713aSLionel Sambuc   }
216f4a2713aSLionel Sambuc   constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'InternalReturnJunk(0)'}}
217f4a2713aSLionel Sambuc 
LToR(int & n)218f4a2713aSLionel Sambuc   constexpr int LToR(int &n) { return n; }
GrabCallersArgument(bool which,int a,int b)219f4a2713aSLionel Sambuc   constexpr int GrabCallersArgument(bool which, int a, int b) {
220f4a2713aSLionel Sambuc     return LToR(which ? b : a);
221f4a2713aSLionel Sambuc   }
222f4a2713aSLionel Sambuc   static_assert(GrabCallersArgument(false, 1, 2) == 1, "");
223f4a2713aSLionel Sambuc   static_assert(GrabCallersArgument(true, 4, 8) == 8, "");
224f4a2713aSLionel Sambuc 
225f4a2713aSLionel Sambuc }
226f4a2713aSLionel Sambuc 
227f4a2713aSLionel Sambuc namespace Pointers {
228f4a2713aSLionel Sambuc 
f(int n,const int * a,const int * b,const int * c)229f4a2713aSLionel Sambuc   constexpr int f(int n, const int *a, const int *b, const int *c) {
230f4a2713aSLionel Sambuc     return n == 0 ? 0 : *a + f(n-1, b, c, a);
231f4a2713aSLionel Sambuc   }
232f4a2713aSLionel Sambuc 
233f4a2713aSLionel Sambuc   const int x = 1, y = 10, z = 100;
234f4a2713aSLionel Sambuc   static_assert(f(23, &x, &y, &z) == 788, "");
235f4a2713aSLionel Sambuc 
g(int n,int a,int b,int c)236f4a2713aSLionel Sambuc   constexpr int g(int n, int a, int b, int c) {
237f4a2713aSLionel Sambuc     return f(n, &a, &b, &c);
238f4a2713aSLionel Sambuc   }
239f4a2713aSLionel Sambuc   static_assert(g(23, x, y, z) == 788, "");
240f4a2713aSLionel Sambuc 
241f4a2713aSLionel Sambuc }
242f4a2713aSLionel Sambuc 
243f4a2713aSLionel Sambuc namespace FunctionPointers {
244f4a2713aSLionel Sambuc 
Double(int n)245f4a2713aSLionel Sambuc   constexpr int Double(int n) { return 2 * n; }
Triple(int n)246f4a2713aSLionel Sambuc   constexpr int Triple(int n) { return 3 * n; }
Twice(int (* F)(int),int n)247f4a2713aSLionel Sambuc   constexpr int Twice(int (*F)(int), int n) { return F(F(n)); }
Quadruple(int n)248f4a2713aSLionel Sambuc   constexpr int Quadruple(int n) { return Twice(Double, n); }
Select(int n)249f4a2713aSLionel Sambuc   constexpr auto Select(int n) -> int (*)(int) {
250f4a2713aSLionel Sambuc     return n == 2 ? &Double : n == 3 ? &Triple : n == 4 ? &Quadruple : 0;
251f4a2713aSLionel Sambuc   }
Apply(int (* F)(int),int n)252f4a2713aSLionel Sambuc   constexpr int Apply(int (*F)(int), int n) { return F(n); } // expected-note {{subexpression}}
253f4a2713aSLionel Sambuc 
254f4a2713aSLionel Sambuc   static_assert(1 + Apply(Select(4), 5) + Apply(Select(3), 7) == 42, "");
255f4a2713aSLionel Sambuc 
256f4a2713aSLionel Sambuc   constexpr int Invalid = Apply(Select(0), 0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'Apply(0, 0)'}}
257f4a2713aSLionel Sambuc 
258f4a2713aSLionel Sambuc }
259f4a2713aSLionel Sambuc 
260f4a2713aSLionel Sambuc namespace PointerComparison {
261f4a2713aSLionel Sambuc 
262f4a2713aSLionel Sambuc int x, y;
263f4a2713aSLionel Sambuc static_assert(&x == &y, "false"); // expected-error {{false}}
264f4a2713aSLionel Sambuc static_assert(&x != &y, "");
265f4a2713aSLionel Sambuc constexpr bool g1 = &x == &y;
266f4a2713aSLionel Sambuc constexpr bool g2 = &x != &y;
267f4a2713aSLionel Sambuc constexpr bool g3 = &x <= &y; // expected-error {{must be initialized by a constant expression}}
268f4a2713aSLionel Sambuc constexpr bool g4 = &x >= &y; // expected-error {{must be initialized by a constant expression}}
269f4a2713aSLionel Sambuc constexpr bool g5 = &x < &y; // expected-error {{must be initialized by a constant expression}}
270f4a2713aSLionel Sambuc constexpr bool g6 = &x > &y; // expected-error {{must be initialized by a constant expression}}
271f4a2713aSLionel Sambuc 
272f4a2713aSLionel Sambuc struct S { int x, y; } s;
273f4a2713aSLionel Sambuc static_assert(&s.x == &s.y, "false"); // expected-error {{false}}
274f4a2713aSLionel Sambuc static_assert(&s.x != &s.y, "");
275f4a2713aSLionel Sambuc static_assert(&s.x <= &s.y, "");
276f4a2713aSLionel Sambuc static_assert(&s.x >= &s.y, "false"); // expected-error {{false}}
277f4a2713aSLionel Sambuc static_assert(&s.x < &s.y, "");
278f4a2713aSLionel Sambuc static_assert(&s.x > &s.y, "false"); // expected-error {{false}}
279f4a2713aSLionel Sambuc 
280f4a2713aSLionel Sambuc static_assert(0 == &y, "false"); // expected-error {{false}}
281f4a2713aSLionel Sambuc static_assert(0 != &y, "");
282f4a2713aSLionel Sambuc constexpr bool n3 = 0 <= &y; // expected-error {{must be initialized by a constant expression}}
283f4a2713aSLionel Sambuc constexpr bool n4 = 0 >= &y; // expected-error {{must be initialized by a constant expression}}
284f4a2713aSLionel Sambuc constexpr bool n5 = 0 < &y; // expected-error {{must be initialized by a constant expression}}
285f4a2713aSLionel Sambuc constexpr bool n6 = 0 > &y; // expected-error {{must be initialized by a constant expression}}
286f4a2713aSLionel Sambuc 
287f4a2713aSLionel Sambuc static_assert(&x == 0, "false"); // expected-error {{false}}
288f4a2713aSLionel Sambuc static_assert(&x != 0, "");
289f4a2713aSLionel Sambuc constexpr bool n9 = &x <= 0; // expected-error {{must be initialized by a constant expression}}
290f4a2713aSLionel Sambuc constexpr bool n10 = &x >= 0; // expected-error {{must be initialized by a constant expression}}
291f4a2713aSLionel Sambuc constexpr bool n11 = &x < 0; // expected-error {{must be initialized by a constant expression}}
292f4a2713aSLionel Sambuc constexpr bool n12 = &x > 0; // expected-error {{must be initialized by a constant expression}}
293f4a2713aSLionel Sambuc 
294f4a2713aSLionel Sambuc static_assert(&x == &x, "");
295f4a2713aSLionel Sambuc static_assert(&x != &x, "false"); // expected-error {{false}}
296f4a2713aSLionel Sambuc static_assert(&x <= &x, "");
297f4a2713aSLionel Sambuc static_assert(&x >= &x, "");
298f4a2713aSLionel Sambuc static_assert(&x < &x, "false"); // expected-error {{false}}
299f4a2713aSLionel Sambuc static_assert(&x > &x, "false"); // expected-error {{false}}
300f4a2713aSLionel Sambuc 
301f4a2713aSLionel Sambuc constexpr S* sptr = &s;
302f4a2713aSLionel Sambuc constexpr bool dyncast = sptr == dynamic_cast<S*>(sptr); // expected-error {{constant expression}} expected-note {{dynamic_cast}}
303f4a2713aSLionel Sambuc 
304f4a2713aSLionel Sambuc struct U {};
305f4a2713aSLionel Sambuc struct Str {
306f4a2713aSLionel Sambuc   int a : dynamic_cast<S*>(sptr) == dynamic_cast<S*>(sptr); // \
307f4a2713aSLionel Sambuc     expected-warning {{not an integral constant expression}} \
308f4a2713aSLionel Sambuc     expected-note {{dynamic_cast is not allowed in a constant expression}}
309f4a2713aSLionel Sambuc   int b : reinterpret_cast<S*>(sptr) == reinterpret_cast<S*>(sptr); // \
310f4a2713aSLionel Sambuc     expected-warning {{not an integral constant expression}} \
311f4a2713aSLionel Sambuc     expected-note {{reinterpret_cast is not allowed in a constant expression}}
312f4a2713aSLionel Sambuc   int c : (S*)(long)(sptr) == (S*)(long)(sptr); // \
313f4a2713aSLionel Sambuc     expected-warning {{not an integral constant expression}} \
314f4a2713aSLionel Sambuc     expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
315f4a2713aSLionel Sambuc   int d : (S*)(42) == (S*)(42); // \
316f4a2713aSLionel Sambuc     expected-warning {{not an integral constant expression}} \
317f4a2713aSLionel Sambuc     expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
318f4a2713aSLionel Sambuc   int e : (Str*)(sptr) == (Str*)(sptr); // \
319f4a2713aSLionel Sambuc     expected-warning {{not an integral constant expression}} \
320f4a2713aSLionel Sambuc     expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
321f4a2713aSLionel Sambuc   int f : &(U&)(*sptr) == &(U&)(*sptr); // \
322f4a2713aSLionel Sambuc     expected-warning {{not an integral constant expression}} \
323f4a2713aSLionel Sambuc     expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
324f4a2713aSLionel Sambuc   int g : (S*)(void*)(sptr) == sptr; // \
325f4a2713aSLionel Sambuc     expected-warning {{not an integral constant expression}} \
326f4a2713aSLionel Sambuc     expected-note {{cast from 'void *' is not allowed in a constant expression}}
327f4a2713aSLionel Sambuc };
328f4a2713aSLionel Sambuc 
329f4a2713aSLionel Sambuc extern char externalvar[];
330f4a2713aSLionel Sambuc constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; // expected-error {{must be initialized by a constant expression}}
331f4a2713aSLionel Sambuc constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} expected-warning {{unspecified}}
332f4a2713aSLionel Sambuc static_assert(0 != "foo", "");
333f4a2713aSLionel Sambuc 
334f4a2713aSLionel Sambuc }
335f4a2713aSLionel Sambuc 
336f4a2713aSLionel Sambuc namespace MaterializeTemporary {
337f4a2713aSLionel Sambuc 
f(const int & r)338f4a2713aSLionel Sambuc constexpr int f(const int &r) { return r; }
339f4a2713aSLionel Sambuc constexpr int n = f(1);
340f4a2713aSLionel Sambuc 
same(const int & a,const int & b)341f4a2713aSLionel Sambuc constexpr bool same(const int &a, const int &b) { return &a == &b; }
sameTemporary(const int & n)342f4a2713aSLionel Sambuc constexpr bool sameTemporary(const int &n) { return same(n, n); }
343f4a2713aSLionel Sambuc 
344f4a2713aSLionel Sambuc static_assert(n, "");
345f4a2713aSLionel Sambuc static_assert(!same(4, 4), "");
346f4a2713aSLionel Sambuc static_assert(same(n, n), "");
347f4a2713aSLionel Sambuc static_assert(sameTemporary(9), "");
348f4a2713aSLionel Sambuc 
349f4a2713aSLionel Sambuc struct A { int &&r; };
350f4a2713aSLionel Sambuc struct B { A &&a1; A &&a2; };
351f4a2713aSLionel Sambuc 
352f4a2713aSLionel Sambuc constexpr B b1 { { 1 }, { 2 } }; // expected-note {{temporary created here}}
353f4a2713aSLionel Sambuc static_assert(&b1.a1 != &b1.a2, "");
354f4a2713aSLionel Sambuc static_assert(&b1.a1.r != &b1.a2.r, ""); // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}}
355f4a2713aSLionel Sambuc 
356f4a2713aSLionel Sambuc constexpr B &&b2 { { 3 }, { 4 } }; // expected-note {{temporary created here}}
357f4a2713aSLionel Sambuc static_assert(&b1 != &b2, "");
358f4a2713aSLionel Sambuc static_assert(&b1.a1 != &b2.a1, ""); // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}}
359f4a2713aSLionel Sambuc 
360f4a2713aSLionel Sambuc constexpr thread_local B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
foo()361f4a2713aSLionel Sambuc void foo() {
362f4a2713aSLionel Sambuc   constexpr static B b1 { { 1 }, { 2 } }; // ok
363f4a2713aSLionel Sambuc   constexpr thread_local B b2 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
364f4a2713aSLionel Sambuc   constexpr B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
365f4a2713aSLionel Sambuc }
366f4a2713aSLionel Sambuc 
367f4a2713aSLionel Sambuc constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} }); // expected-warning 4{{unused}}
368f4a2713aSLionel Sambuc static_assert(&b4 != &b2, "");
369f4a2713aSLionel Sambuc 
370f4a2713aSLionel Sambuc // Proposed DR: copy-elision doesn't trigger lifetime extension.
371f4a2713aSLionel Sambuc constexpr B b5 = B{ {0}, {0} }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
372f4a2713aSLionel Sambuc 
373f4a2713aSLionel Sambuc namespace NestedNonStatic {
374f4a2713aSLionel Sambuc   // Proposed DR: for a reference constant expression to refer to a static
375f4a2713aSLionel Sambuc   // storage duration temporary, that temporary must itself be initialized
376f4a2713aSLionel Sambuc   // by a constant expression (a core constant expression is not enough).
377f4a2713aSLionel Sambuc   struct A { int &&r; };
378f4a2713aSLionel Sambuc   struct B { A &&a; };
379f4a2713aSLionel Sambuc   constexpr B a = { A{0} }; // ok
380f4a2713aSLionel Sambuc   constexpr B b = { A(A{0}) }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
381f4a2713aSLionel Sambuc }
382f4a2713aSLionel Sambuc 
383f4a2713aSLionel Sambuc namespace FakeInitList {
384f4a2713aSLionel Sambuc   struct init_list_3_ints { const int (&x)[3]; };
385f4a2713aSLionel Sambuc   struct init_list_2_init_list_3_ints { const init_list_3_ints (&x)[2]; };
386f4a2713aSLionel Sambuc   constexpr init_list_2_init_list_3_ints ils = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } };
387f4a2713aSLionel Sambuc }
388f4a2713aSLionel Sambuc 
389f4a2713aSLionel Sambuc }
390f4a2713aSLionel Sambuc 
strcmp_ce(const char * p,const char * q)391f4a2713aSLionel Sambuc constexpr int strcmp_ce(const char *p, const char *q) {
392f4a2713aSLionel Sambuc   return (!*p || *p != *q) ? *p - *q : strcmp_ce(p+1, q+1);
393f4a2713aSLionel Sambuc }
394f4a2713aSLionel Sambuc 
395f4a2713aSLionel Sambuc namespace StringLiteral {
396f4a2713aSLionel Sambuc 
397f4a2713aSLionel Sambuc template<typename Char>
MangleChars(const Char * p)398f4a2713aSLionel Sambuc constexpr int MangleChars(const Char *p) {
399f4a2713aSLionel Sambuc   return *p + 3 * (*p ? MangleChars(p+1) : 0);
400f4a2713aSLionel Sambuc }
401f4a2713aSLionel Sambuc 
402f4a2713aSLionel Sambuc static_assert(MangleChars("constexpr!") == 1768383, "");
403f4a2713aSLionel Sambuc static_assert(MangleChars(u8"constexpr!") == 1768383, "");
404f4a2713aSLionel Sambuc static_assert(MangleChars(L"constexpr!") == 1768383, "");
405f4a2713aSLionel Sambuc static_assert(MangleChars(u"constexpr!") == 1768383, "");
406f4a2713aSLionel Sambuc static_assert(MangleChars(U"constexpr!") == 1768383, "");
407f4a2713aSLionel Sambuc 
408f4a2713aSLionel Sambuc constexpr char c0 = "nought index"[0];
409f4a2713aSLionel Sambuc constexpr char c1 = "nice index"[10];
410f4a2713aSLionel Sambuc constexpr 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}}
411f4a2713aSLionel Sambuc constexpr 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}}
412f4a2713aSLionel Sambuc constexpr 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}}
413f4a2713aSLionel Sambuc 
414f4a2713aSLionel Sambuc constexpr const char *p = "test" + 2;
415f4a2713aSLionel Sambuc static_assert(*p == 's', "");
416f4a2713aSLionel Sambuc 
max_iter(const char * a,const char * b)417f4a2713aSLionel Sambuc constexpr const char *max_iter(const char *a, const char *b) {
418f4a2713aSLionel Sambuc   return *a < *b ? b : a;
419f4a2713aSLionel Sambuc }
max_element(const char * a,const char * b)420f4a2713aSLionel Sambuc constexpr const char *max_element(const char *a, const char *b) {
421f4a2713aSLionel Sambuc   return (a+1 >= b) ? a : max_iter(a, max_element(a+1, b));
422f4a2713aSLionel Sambuc }
423f4a2713aSLionel Sambuc 
424f4a2713aSLionel Sambuc constexpr char str[] = "the quick brown fox jumped over the lazy dog";
425f4a2713aSLionel Sambuc constexpr const char *max = max_element(begin(str), end(str));
426f4a2713aSLionel Sambuc static_assert(*max == 'z', "");
427f4a2713aSLionel Sambuc static_assert(max == str + 38, "");
428f4a2713aSLionel Sambuc 
429f4a2713aSLionel Sambuc static_assert(strcmp_ce("hello world", "hello world") == 0, "");
430f4a2713aSLionel Sambuc static_assert(strcmp_ce("hello world", "hello clang") > 0, "");
431f4a2713aSLionel Sambuc static_assert(strcmp_ce("constexpr", "test") < 0, "");
432f4a2713aSLionel Sambuc static_assert(strcmp_ce("", " ") < 0, "");
433f4a2713aSLionel Sambuc 
434f4a2713aSLionel Sambuc struct S {
435f4a2713aSLionel Sambuc   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}}
436f4a2713aSLionel Sambuc };
437f4a2713aSLionel Sambuc 
438f4a2713aSLionel Sambuc struct T {
439f4a2713aSLionel Sambuc   char c[6];
TStringLiteral::T440f4a2713aSLionel Sambuc   constexpr T() : c{"foo"} {}
441f4a2713aSLionel Sambuc };
442f4a2713aSLionel Sambuc constexpr T t;
443f4a2713aSLionel Sambuc 
444f4a2713aSLionel Sambuc static_assert(t.c[0] == 'f', "");
445f4a2713aSLionel Sambuc static_assert(t.c[1] == 'o', "");
446f4a2713aSLionel Sambuc static_assert(t.c[2] == 'o', "");
447f4a2713aSLionel Sambuc static_assert(t.c[3] == 0, "");
448f4a2713aSLionel Sambuc static_assert(t.c[4] == 0, "");
449f4a2713aSLionel Sambuc static_assert(t.c[5] == 0, "");
450f4a2713aSLionel Sambuc static_assert(t.c[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
451f4a2713aSLionel Sambuc 
452f4a2713aSLionel Sambuc struct U {
453f4a2713aSLionel Sambuc   wchar_t chars[6];
454f4a2713aSLionel Sambuc   int n;
455f4a2713aSLionel Sambuc } constexpr u = { { L"test" }, 0 };
456f4a2713aSLionel Sambuc static_assert(u.chars[2] == L's', "");
457f4a2713aSLionel Sambuc 
458f4a2713aSLionel Sambuc struct V {
459f4a2713aSLionel Sambuc   char c[4];
VStringLiteral::V460f4a2713aSLionel Sambuc   constexpr V() : c("hi!") {}
461f4a2713aSLionel Sambuc };
462f4a2713aSLionel Sambuc static_assert(V().c[1] == "i"[0], "");
463f4a2713aSLionel Sambuc 
464f4a2713aSLionel Sambuc namespace Parens {
465f4a2713aSLionel Sambuc   constexpr unsigned char a[] = ("foo"), b[] = {"foo"}, c[] = {("foo")},
466f4a2713aSLionel Sambuc                           d[4] = ("foo"), e[5] = {"foo"}, f[6] = {("foo")};
467f4a2713aSLionel Sambuc   static_assert(a[0] == 'f', "");
468f4a2713aSLionel Sambuc   static_assert(b[1] == 'o', "");
469f4a2713aSLionel Sambuc   static_assert(c[2] == 'o', "");
470f4a2713aSLionel Sambuc   static_assert(d[0] == 'f', "");
471f4a2713aSLionel Sambuc   static_assert(e[1] == 'o', "");
472f4a2713aSLionel Sambuc   static_assert(f[2] == 'o', "");
473f4a2713aSLionel Sambuc   static_assert(f[5] == 0, "");
474f4a2713aSLionel Sambuc   static_assert(f[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
475f4a2713aSLionel Sambuc }
476f4a2713aSLionel Sambuc 
477f4a2713aSLionel Sambuc }
478f4a2713aSLionel Sambuc 
479f4a2713aSLionel Sambuc namespace Array {
480f4a2713aSLionel Sambuc 
481f4a2713aSLionel Sambuc template<typename Iter>
Sum(Iter begin,Iter end)482f4a2713aSLionel Sambuc constexpr auto Sum(Iter begin, Iter end) -> decltype(+*begin) {
483f4a2713aSLionel Sambuc   return begin == end ? 0 : *begin + Sum(begin+1, end);
484f4a2713aSLionel Sambuc }
485f4a2713aSLionel Sambuc 
486f4a2713aSLionel Sambuc constexpr int xs[] = { 1, 2, 3, 4, 5 };
487f4a2713aSLionel Sambuc constexpr int ys[] = { 5, 4, 3, 2, 1 };
488f4a2713aSLionel Sambuc constexpr int sum_xs = Sum(begin(xs), end(xs));
489f4a2713aSLionel Sambuc static_assert(sum_xs == 15, "");
490f4a2713aSLionel Sambuc 
ZipFoldR(int (* F)(int x,int y,int c),int n,const int * xs,const int * ys,int c)491f4a2713aSLionel Sambuc constexpr int ZipFoldR(int (*F)(int x, int y, int c), int n,
492f4a2713aSLionel Sambuc                        const int *xs, const int *ys, int c) {
493f4a2713aSLionel Sambuc   return n ? F(
494f4a2713aSLionel Sambuc                *xs, // expected-note {{read of dereferenced one-past-the-end pointer}}
495f4a2713aSLionel Sambuc                *ys,
496f4a2713aSLionel Sambuc                ZipFoldR(F, n-1, xs+1, ys+1, c)) // \
497f4a2713aSLionel Sambuc       expected-note {{in call to 'ZipFoldR(&SubMul, 2, &xs[4], &ys[4], 1)'}} \
498f4a2713aSLionel Sambuc       expected-note {{in call to 'ZipFoldR(&SubMul, 1, &xs[5], &ys[5], 1)'}}
499f4a2713aSLionel Sambuc            : c;
500f4a2713aSLionel Sambuc }
MulAdd(int x,int y,int c)501f4a2713aSLionel Sambuc constexpr int MulAdd(int x, int y, int c) { return x * y + c; }
502f4a2713aSLionel Sambuc constexpr int InnerProduct = ZipFoldR(MulAdd, 5, xs, ys, 0);
503f4a2713aSLionel Sambuc static_assert(InnerProduct == 35, "");
504f4a2713aSLionel Sambuc 
SubMul(int x,int y,int c)505f4a2713aSLionel Sambuc constexpr int SubMul(int x, int y, int c) { return (x - y) * c; }
506f4a2713aSLionel Sambuc constexpr int DiffProd = ZipFoldR(SubMul, 2, xs+3, ys+3, 1);
507f4a2713aSLionel Sambuc static_assert(DiffProd == 8, "");
508f4a2713aSLionel Sambuc static_assert(ZipFoldR(SubMul, 3, xs+3, ys+3, 1), ""); // \
509f4a2713aSLionel Sambuc       expected-error {{constant expression}} \
510f4a2713aSLionel Sambuc       expected-note {{in call to 'ZipFoldR(&SubMul, 3, &xs[3], &ys[3], 1)'}}
511f4a2713aSLionel Sambuc 
512f4a2713aSLionel Sambuc constexpr const int *p = xs + 3;
513f4a2713aSLionel Sambuc constexpr int xs4 = p[1]; // ok
514f4a2713aSLionel Sambuc constexpr int xs5 = p[2]; // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
515f4a2713aSLionel Sambuc constexpr int xs6 = p[3]; // expected-error {{constant expression}} expected-note {{cannot refer to element 6}}
516f4a2713aSLionel Sambuc constexpr int xs0 = p[-3]; // ok
517f4a2713aSLionel Sambuc constexpr int xs_1 = p[-4]; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
518f4a2713aSLionel Sambuc 
519f4a2713aSLionel Sambuc constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
520f4a2713aSLionel Sambuc static_assert(zs[0][0][0][0] == 1, "");
521f4a2713aSLionel Sambuc static_assert(zs[1][1][1][1] == 16, "");
522f4a2713aSLionel Sambuc static_assert(zs[0][0][0][2] == 3, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
523f4a2713aSLionel Sambuc static_assert((&zs[0][0][0][2])[-1] == 2, "");
524f4a2713aSLionel Sambuc static_assert(**(**(zs + 1) + 1) == 11, "");
525f4a2713aSLionel Sambuc static_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}}
526f4a2713aSLionel Sambuc static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2) == 11, "");
527f4a2713aSLionel Sambuc constexpr 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}}
528f4a2713aSLionel Sambuc 
fail(const int & p)529f4a2713aSLionel Sambuc constexpr int fail(const int &p) {
530f4a2713aSLionel Sambuc   return (&p)[64]; // expected-note {{cannot refer to element 64 of array of 2 elements}}
531f4a2713aSLionel Sambuc }
532f4a2713aSLionel Sambuc static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2)) == 11, ""); // \
533f4a2713aSLionel Sambuc expected-error {{static_assert expression is not an integral constant expression}} \
534f4a2713aSLionel Sambuc expected-note {{in call to 'fail(zs[1][0][1][0])'}}
535f4a2713aSLionel Sambuc 
536f4a2713aSLionel Sambuc constexpr int arr[40] = { 1, 2, 3, [8] = 4 }; // expected-warning {{C99 feature}}
SumNonzero(const int * p)537f4a2713aSLionel Sambuc constexpr int SumNonzero(const int *p) {
538f4a2713aSLionel Sambuc   return *p + (*p ? SumNonzero(p+1) : 0);
539f4a2713aSLionel Sambuc }
CountZero(const int * p,const int * q)540f4a2713aSLionel Sambuc constexpr int CountZero(const int *p, const int *q) {
541f4a2713aSLionel Sambuc   return p == q ? 0 : (*p == 0) + CountZero(p+1, q);
542f4a2713aSLionel Sambuc }
543f4a2713aSLionel Sambuc static_assert(SumNonzero(arr) == 6, "");
544f4a2713aSLionel Sambuc static_assert(CountZero(arr, arr + 40) == 36, "");
545f4a2713aSLionel Sambuc 
546f4a2713aSLionel Sambuc struct ArrayElem {
ArrayElemArray::ArrayElem547f4a2713aSLionel Sambuc   constexpr ArrayElem() : n(0) {}
548f4a2713aSLionel Sambuc   int n;
fArray::ArrayElem549f4a2713aSLionel Sambuc   constexpr int f() const { return n; }
550f4a2713aSLionel Sambuc };
551f4a2713aSLionel Sambuc struct ArrayRVal {
ArrayRValArray::ArrayRVal552f4a2713aSLionel Sambuc   constexpr ArrayRVal() {}
553f4a2713aSLionel Sambuc   ArrayElem elems[10];
554f4a2713aSLionel Sambuc };
555f4a2713aSLionel Sambuc static_assert(ArrayRVal().elems[3].f() == 0, "");
556f4a2713aSLionel Sambuc 
557f4a2713aSLionel Sambuc constexpr int selfref[2][2][2] = {
558f4a2713aSLionel Sambuc   selfref[1][1][1] + 1, selfref[0][0][0] + 1,
559f4a2713aSLionel Sambuc   selfref[1][0][1] + 1, selfref[0][1][0] + 1,
560f4a2713aSLionel Sambuc   selfref[1][0][0] + 1, selfref[0][1][1] + 1 };
561f4a2713aSLionel Sambuc static_assert(selfref[0][0][0] == 1, "");
562f4a2713aSLionel Sambuc static_assert(selfref[0][0][1] == 2, "");
563f4a2713aSLionel Sambuc static_assert(selfref[0][1][0] == 1, "");
564f4a2713aSLionel Sambuc static_assert(selfref[0][1][1] == 2, "");
565f4a2713aSLionel Sambuc static_assert(selfref[1][0][0] == 1, "");
566f4a2713aSLionel Sambuc static_assert(selfref[1][0][1] == 3, "");
567f4a2713aSLionel Sambuc static_assert(selfref[1][1][0] == 0, "");
568f4a2713aSLionel Sambuc static_assert(selfref[1][1][1] == 0, "");
569f4a2713aSLionel Sambuc 
570f4a2713aSLionel Sambuc struct TrivialDefCtor { int n; };
571f4a2713aSLionel Sambuc typedef TrivialDefCtor TDCArray[2][2];
572f4a2713aSLionel Sambuc static_assert(TDCArray{}[1][1].n == 0, "");
573f4a2713aSLionel Sambuc 
574f4a2713aSLionel Sambuc struct NonAggregateTDC : TrivialDefCtor {};
575f4a2713aSLionel Sambuc typedef NonAggregateTDC NATDCArray[2][2];
576f4a2713aSLionel Sambuc static_assert(NATDCArray{}[1][1].n == 0, "");
577f4a2713aSLionel Sambuc 
578f4a2713aSLionel Sambuc }
579f4a2713aSLionel Sambuc 
580f4a2713aSLionel Sambuc namespace DependentValues {
581f4a2713aSLionel Sambuc 
582f4a2713aSLionel Sambuc struct I { int n; typedef I V[10]; };
583f4a2713aSLionel Sambuc I::V x, y;
584f4a2713aSLionel Sambuc int g();
585f4a2713aSLionel Sambuc template<bool B, typename T> struct S : T {
586f4a2713aSLionel Sambuc   int k;
fDependentValues::S587f4a2713aSLionel Sambuc   void f() {
588f4a2713aSLionel Sambuc     I::V &cells = B ? x : y;
589f4a2713aSLionel Sambuc     I &i = cells[k];
590f4a2713aSLionel Sambuc     switch (i.n) {}
591f4a2713aSLionel Sambuc 
592f4a2713aSLionel Sambuc     // FIXME: We should be able to diagnose this.
593f4a2713aSLionel Sambuc     constexpr int n = g();
594f4a2713aSLionel Sambuc 
595f4a2713aSLionel Sambuc     constexpr int m = this->g(); // ok, could be constexpr
596f4a2713aSLionel Sambuc   }
597f4a2713aSLionel Sambuc };
598f4a2713aSLionel Sambuc 
599f4a2713aSLionel Sambuc }
600f4a2713aSLionel Sambuc 
601f4a2713aSLionel Sambuc namespace Class {
602f4a2713aSLionel Sambuc 
AClass::A603f4a2713aSLionel Sambuc struct A { constexpr A(int a, int b) : k(a + b) {} int k; };
fn(const A & a)604f4a2713aSLionel Sambuc constexpr int fn(const A &a) { return a.k; }
605f4a2713aSLionel Sambuc static_assert(fn(A(4,5)) == 9, "");
606f4a2713aSLionel Sambuc 
607*0a6a1f1dSLionel Sambuc struct B { int n; int m; } constexpr b = { 0, b.n };
608f4a2713aSLionel Sambuc struct C {
CClass::C609f4a2713aSLionel Sambuc   constexpr C(C *this_) : m(42), n(this_->m) {} // ok
610f4a2713aSLionel Sambuc   int m, n;
611f4a2713aSLionel Sambuc };
612f4a2713aSLionel Sambuc struct D {
613f4a2713aSLionel Sambuc   C c;
DClass::D614f4a2713aSLionel Sambuc   constexpr D() : c(&c) {}
615f4a2713aSLionel Sambuc };
616f4a2713aSLionel Sambuc static_assert(D().c.n == 42, "");
617f4a2713aSLionel Sambuc 
618f4a2713aSLionel Sambuc struct E {
EClass::E619f4a2713aSLionel Sambuc   constexpr E() : p(&p) {}
620f4a2713aSLionel Sambuc   void *p;
621f4a2713aSLionel Sambuc };
622f4a2713aSLionel Sambuc constexpr const E &e1 = E();
623f4a2713aSLionel Sambuc // This is a constant expression if we elide the copy constructor call, and
624f4a2713aSLionel Sambuc // is not a constant expression if we don't! But we do, so it is.
625f4a2713aSLionel Sambuc constexpr E e2 = E();
626f4a2713aSLionel Sambuc static_assert(e2.p == &e2.p, "");
627f4a2713aSLionel Sambuc constexpr E e3;
628f4a2713aSLionel Sambuc static_assert(e3.p == &e3.p, "");
629f4a2713aSLionel Sambuc 
630f4a2713aSLionel Sambuc extern const class F f;
631f4a2713aSLionel Sambuc struct F {
FClass::F632f4a2713aSLionel Sambuc   constexpr F() : p(&f.p) {}
633f4a2713aSLionel Sambuc   const void *p;
634f4a2713aSLionel Sambuc };
635f4a2713aSLionel Sambuc constexpr F f;
636f4a2713aSLionel Sambuc 
637f4a2713aSLionel Sambuc struct G {
638f4a2713aSLionel Sambuc   struct T {
TClass::G::T639f4a2713aSLionel Sambuc     constexpr T(T *p) : u1(), u2(p) {}
640f4a2713aSLionel Sambuc     union U1 {
U1()641f4a2713aSLionel Sambuc       constexpr U1() {}
642f4a2713aSLionel Sambuc       int a, b = 42;
643f4a2713aSLionel Sambuc     } u1;
644f4a2713aSLionel Sambuc     union U2 {
U2(T * p)645f4a2713aSLionel Sambuc       constexpr U2(T *p) : c(p->u1.b) {}
646f4a2713aSLionel Sambuc       int c, d;
647f4a2713aSLionel Sambuc     } u2;
648f4a2713aSLionel Sambuc   } t;
GClass::G649f4a2713aSLionel Sambuc   constexpr G() : t(&t) {}
650f4a2713aSLionel Sambuc } constexpr g;
651f4a2713aSLionel Sambuc 
652f4a2713aSLionel Sambuc static_assert(g.t.u1.a == 42, ""); // expected-error {{constant expression}} expected-note {{read of member 'a' of union with active member 'b'}}
653f4a2713aSLionel Sambuc static_assert(g.t.u1.b == 42, "");
654f4a2713aSLionel Sambuc static_assert(g.t.u2.c == 42, "");
655f4a2713aSLionel Sambuc static_assert(g.t.u2.d == 42, ""); // expected-error {{constant expression}} expected-note {{read of member 'd' of union with active member 'c'}}
656f4a2713aSLionel Sambuc 
657f4a2713aSLionel Sambuc struct S {
658f4a2713aSLionel Sambuc   int a, b;
659f4a2713aSLionel Sambuc   const S *p;
660f4a2713aSLionel Sambuc   double d;
661f4a2713aSLionel Sambuc   const char *q;
662f4a2713aSLionel Sambuc 
SClass::S663f4a2713aSLionel Sambuc   constexpr S(int n, const S *p) : a(5), b(n), p(p), d(n), q("hello") {}
664f4a2713aSLionel Sambuc };
665f4a2713aSLionel Sambuc 
666f4a2713aSLionel Sambuc S global(43, &global);
667f4a2713aSLionel Sambuc 
668f4a2713aSLionel Sambuc static_assert(S(15, &global).b == 15, "");
669f4a2713aSLionel Sambuc 
CheckS(const S & s)670f4a2713aSLionel Sambuc constexpr bool CheckS(const S &s) {
671f4a2713aSLionel Sambuc   return s.a == 5 && s.b == 27 && s.p == &global && s.d == 27. && s.q[3] == 'l';
672f4a2713aSLionel Sambuc }
673f4a2713aSLionel Sambuc static_assert(CheckS(S(27, &global)), "");
674f4a2713aSLionel Sambuc 
675f4a2713aSLionel Sambuc struct Arr {
676f4a2713aSLionel Sambuc   char arr[3];
ArrClass::Arr677f4a2713aSLionel Sambuc   constexpr Arr() : arr{'x', 'y', 'z'} {}
678f4a2713aSLionel Sambuc };
hash(Arr && a)679f4a2713aSLionel Sambuc constexpr int hash(Arr &&a) {
680f4a2713aSLionel Sambuc   return a.arr[0] + a.arr[1] * 0x100 + a.arr[2] * 0x10000;
681f4a2713aSLionel Sambuc }
682f4a2713aSLionel Sambuc constexpr int k = hash(Arr());
683f4a2713aSLionel Sambuc static_assert(k == 0x007a7978, "");
684f4a2713aSLionel Sambuc 
685f4a2713aSLionel Sambuc 
686f4a2713aSLionel Sambuc struct AggregateInit {
687f4a2713aSLionel Sambuc   const char &c;
688f4a2713aSLionel Sambuc   int n;
689f4a2713aSLionel Sambuc   double d;
690f4a2713aSLionel Sambuc   int arr[5];
691f4a2713aSLionel Sambuc   void *p;
692f4a2713aSLionel Sambuc };
693f4a2713aSLionel Sambuc 
694f4a2713aSLionel Sambuc constexpr AggregateInit agg1 = { "hello"[0] };
695f4a2713aSLionel Sambuc 
696f4a2713aSLionel Sambuc static_assert(strcmp_ce(&agg1.c, "hello") == 0, "");
697f4a2713aSLionel Sambuc static_assert(agg1.n == 0, "");
698f4a2713aSLionel Sambuc static_assert(agg1.d == 0.0, "");
699f4a2713aSLionel Sambuc static_assert(agg1.arr[-1] == 0, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
700f4a2713aSLionel Sambuc static_assert(agg1.arr[0] == 0, "");
701f4a2713aSLionel Sambuc static_assert(agg1.arr[4] == 0, "");
702f4a2713aSLionel Sambuc static_assert(agg1.arr[5] == 0, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end}}
703f4a2713aSLionel Sambuc static_assert(agg1.p == nullptr, "");
704f4a2713aSLionel Sambuc 
705f4a2713aSLionel Sambuc static constexpr const unsigned char uc[] = { "foo" };
706f4a2713aSLionel Sambuc static_assert(uc[0] == 'f', "");
707f4a2713aSLionel Sambuc static_assert(uc[3] == 0, "");
708f4a2713aSLionel Sambuc 
709f4a2713aSLionel Sambuc namespace SimpleDerivedClass {
710f4a2713aSLionel Sambuc 
711f4a2713aSLionel Sambuc struct B {
BClass::SimpleDerivedClass::B712f4a2713aSLionel Sambuc   constexpr B(int n) : a(n) {}
713f4a2713aSLionel Sambuc   int a;
714f4a2713aSLionel Sambuc };
715f4a2713aSLionel Sambuc struct D : B {
DClass::SimpleDerivedClass::D716f4a2713aSLionel Sambuc   constexpr D(int n) : B(n) {}
717f4a2713aSLionel Sambuc };
718f4a2713aSLionel Sambuc constexpr D d(3);
719f4a2713aSLionel Sambuc static_assert(d.a == 3, "");
720f4a2713aSLionel Sambuc 
721f4a2713aSLionel Sambuc }
722f4a2713aSLionel Sambuc 
BottomClass::Bottom723f4a2713aSLionel Sambuc struct Bottom { constexpr Bottom() {} };
724f4a2713aSLionel Sambuc struct Base : Bottom {
BaseClass::Base725f4a2713aSLionel Sambuc   constexpr Base(int a = 42, const char *b = "test") : a(a), b(b) {}
726f4a2713aSLionel Sambuc   int a;
727f4a2713aSLionel Sambuc   const char *b;
728f4a2713aSLionel Sambuc };
729f4a2713aSLionel Sambuc struct Base2 : Bottom {
Base2Class::Base2730f4a2713aSLionel Sambuc   constexpr Base2(const int &r) : r(r) {}
731f4a2713aSLionel Sambuc   int q = 123;
732f4a2713aSLionel Sambuc   const int &r;
733f4a2713aSLionel Sambuc };
734f4a2713aSLionel Sambuc struct Derived : Base, Base2 {
DerivedClass::Derived735f4a2713aSLionel Sambuc   constexpr Derived() : Base(76), Base2(a) {}
736f4a2713aSLionel Sambuc   int c = r + b[1];
737f4a2713aSLionel Sambuc };
738f4a2713aSLionel Sambuc 
operator ==(const Base & a,const Base & b)739f4a2713aSLionel Sambuc constexpr bool operator==(const Base &a, const Base &b) {
740f4a2713aSLionel Sambuc   return a.a == b.a && strcmp_ce(a.b, b.b) == 0;
741f4a2713aSLionel Sambuc }
742f4a2713aSLionel Sambuc 
743f4a2713aSLionel Sambuc constexpr Base base;
744f4a2713aSLionel Sambuc constexpr Base base2(76);
745f4a2713aSLionel Sambuc constexpr Derived derived;
746f4a2713aSLionel Sambuc static_assert(derived.a == 76, "");
747f4a2713aSLionel Sambuc static_assert(derived.b[2] == 's', "");
748f4a2713aSLionel Sambuc static_assert(derived.c == 76 + 'e', "");
749f4a2713aSLionel Sambuc static_assert(derived.q == 123, "");
750f4a2713aSLionel Sambuc static_assert(derived.r == 76, "");
751f4a2713aSLionel Sambuc static_assert(&derived.r == &derived.a, "");
752f4a2713aSLionel Sambuc 
753f4a2713aSLionel Sambuc static_assert(!(derived == base), "");
754f4a2713aSLionel Sambuc static_assert(derived == base2, "");
755f4a2713aSLionel Sambuc 
756f4a2713aSLionel Sambuc constexpr Bottom &bot1 = (Base&)derived;
757f4a2713aSLionel Sambuc constexpr Bottom &bot2 = (Base2&)derived;
758f4a2713aSLionel Sambuc static_assert(&bot1 != &bot2, "");
759f4a2713aSLionel Sambuc 
760f4a2713aSLionel Sambuc constexpr Bottom *pb1 = (Base*)&derived;
761f4a2713aSLionel Sambuc constexpr Bottom *pb2 = (Base2*)&derived;
762f4a2713aSLionel Sambuc static_assert(&pb1 != &pb2, "");
763f4a2713aSLionel Sambuc static_assert(pb1 == &bot1, "");
764f4a2713aSLionel Sambuc static_assert(pb2 == &bot2, "");
765f4a2713aSLionel Sambuc 
766f4a2713aSLionel Sambuc constexpr Base2 &fail = (Base2&)bot1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}}
767f4a2713aSLionel Sambuc constexpr Base &fail2 = (Base&)*pb2; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base'}}
768f4a2713aSLionel Sambuc constexpr Base2 &ok2 = (Base2&)bot2;
769f4a2713aSLionel Sambuc static_assert(&ok2 == &derived, "");
770f4a2713aSLionel Sambuc 
771f4a2713aSLionel Sambuc constexpr Base2 *pfail = (Base2*)pb1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}}
772f4a2713aSLionel Sambuc constexpr Base *pfail2 = (Base*)&bot2; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base'}}
773f4a2713aSLionel Sambuc constexpr Base2 *pok2 = (Base2*)pb2;
774f4a2713aSLionel Sambuc static_assert(pok2 == &derived, "");
775f4a2713aSLionel Sambuc static_assert(&ok2 == pok2, "");
776f4a2713aSLionel Sambuc static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");
777f4a2713aSLionel Sambuc static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
778f4a2713aSLionel Sambuc 
779f4a2713aSLionel Sambuc // Core issue 903: we do not perform constant evaluation when checking for a
780f4a2713aSLionel Sambuc // null pointer in C++11. Just check for an integer literal with value 0.
781f4a2713aSLionel Sambuc constexpr Base *nullB = 42 - 6 * 7; // expected-error {{cannot initialize a variable of type 'Class::Base *const' with an rvalue of type 'int'}}
782f4a2713aSLionel Sambuc constexpr Base *nullB1 = 0;
783f4a2713aSLionel Sambuc static_assert((Bottom*)nullB == 0, "");
784f4a2713aSLionel Sambuc static_assert((Derived*)nullB == 0, "");
785f4a2713aSLionel Sambuc static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");
786f4a2713aSLionel Sambuc Base *nullB2 = '\0'; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'char'}}
787f4a2713aSLionel Sambuc Base *nullB3 = (0);
788f4a2713aSLionel Sambuc Base *nullB4 = false; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'bool'}}
789f4a2713aSLionel Sambuc Base *nullB5 = ((0ULL));
790f4a2713aSLionel Sambuc Base *nullB6 = 0.; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'double'}}
791f4a2713aSLionel Sambuc enum Null { kNull };
792f4a2713aSLionel Sambuc Base *nullB7 = kNull; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'Class::Null'}}
793f4a2713aSLionel Sambuc static_assert(nullB1 == (1 - 1), ""); // expected-error {{comparison between pointer and integer}}
794f4a2713aSLionel Sambuc 
795f4a2713aSLionel Sambuc 
796f4a2713aSLionel Sambuc 
797f4a2713aSLionel Sambuc namespace ConversionOperators {
798f4a2713aSLionel Sambuc 
799f4a2713aSLionel Sambuc struct T {
TClass::ConversionOperators::T800f4a2713aSLionel Sambuc   constexpr T(int n) : k(5*n - 3) {}
operator intClass::ConversionOperators::T801f4a2713aSLionel Sambuc   constexpr operator int() const { return k; }
802f4a2713aSLionel Sambuc   int k;
803f4a2713aSLionel Sambuc };
804f4a2713aSLionel Sambuc 
805f4a2713aSLionel Sambuc struct S {
SClass::ConversionOperators::S806f4a2713aSLionel Sambuc   constexpr S(int n) : k(2*n + 1) {}
operator intClass::ConversionOperators::S807f4a2713aSLionel Sambuc   constexpr operator int() const { return k; }
operator TClass::ConversionOperators::S808f4a2713aSLionel Sambuc   constexpr operator T() const { return T(k); }
809f4a2713aSLionel Sambuc   int k;
810f4a2713aSLionel Sambuc };
811f4a2713aSLionel Sambuc 
check(T a,T b)812f4a2713aSLionel Sambuc constexpr bool check(T a, T b) { return a == b.k; }
813f4a2713aSLionel Sambuc 
814f4a2713aSLionel Sambuc static_assert(S(5) == 11, "");
815f4a2713aSLionel Sambuc static_assert(check(S(5), 11), "");
816f4a2713aSLionel Sambuc 
817f4a2713aSLionel Sambuc namespace PR14171 {
818f4a2713aSLionel Sambuc 
819f4a2713aSLionel Sambuc struct X {
820f4a2713aSLionel Sambuc   constexpr (operator int)() const { return 0; }
821f4a2713aSLionel Sambuc };
822f4a2713aSLionel Sambuc static_assert(X() == 0, "");
823f4a2713aSLionel Sambuc 
824f4a2713aSLionel Sambuc }
825f4a2713aSLionel Sambuc 
826f4a2713aSLionel Sambuc }
827f4a2713aSLionel Sambuc 
828*0a6a1f1dSLionel Sambuc struct This {
fClass::This829*0a6a1f1dSLionel Sambuc   constexpr int f() const { return 0; }
gClass::This830*0a6a1f1dSLionel Sambuc   static constexpr int g() { return 0; }
hClass::This831*0a6a1f1dSLionel Sambuc   void h() {
832*0a6a1f1dSLionel Sambuc     constexpr int x = f(); // expected-error {{must be initialized by a constant}}
833*0a6a1f1dSLionel Sambuc     // expected-note@-1 {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}
834*0a6a1f1dSLionel Sambuc     constexpr int y = this->f(); // expected-error {{must be initialized by a constant}}
835*0a6a1f1dSLionel Sambuc     // expected-note-re@-1 {{{{^}}use of 'this' pointer}}
836*0a6a1f1dSLionel Sambuc     constexpr int z = g();
837*0a6a1f1dSLionel Sambuc     static_assert(z == 0, "");
838*0a6a1f1dSLionel Sambuc   }
839*0a6a1f1dSLionel Sambuc };
840*0a6a1f1dSLionel Sambuc 
841f4a2713aSLionel Sambuc }
842f4a2713aSLionel Sambuc 
843f4a2713aSLionel Sambuc namespace Temporaries {
844f4a2713aSLionel Sambuc 
845f4a2713aSLionel Sambuc struct S {
STemporaries::S846f4a2713aSLionel Sambuc   constexpr S() {}
847f4a2713aSLionel Sambuc   constexpr int f() const;
848f4a2713aSLionel Sambuc   constexpr int g() const;
849f4a2713aSLionel Sambuc };
850f4a2713aSLionel Sambuc struct T : S {
TTemporaries::T851f4a2713aSLionel Sambuc   constexpr T(int n) : S(), n(n) {}
852f4a2713aSLionel Sambuc   int n;
853f4a2713aSLionel Sambuc };
f() const854f4a2713aSLionel Sambuc constexpr int S::f() const {
855f4a2713aSLionel Sambuc   return static_cast<const T*>(this)->n; // expected-note {{cannot cast}}
856f4a2713aSLionel Sambuc }
g() const857f4a2713aSLionel Sambuc constexpr int S::g() const {
858f4a2713aSLionel Sambuc   // FIXME: Better diagnostic for this.
859f4a2713aSLionel Sambuc   return this->*(int(S::*))&T::n; // expected-note {{subexpression}}
860f4a2713aSLionel Sambuc }
861f4a2713aSLionel Sambuc // The T temporary is implicitly cast to an S subobject, but we can recover the
862f4a2713aSLionel Sambuc // T full-object via a base-to-derived cast, or a derived-to-base-casted member
863f4a2713aSLionel Sambuc // pointer.
864f4a2713aSLionel Sambuc static_assert(S().f(), ""); // expected-error {{constant expression}} expected-note {{in call to '&Temporaries::S()->f()'}}
865f4a2713aSLionel Sambuc static_assert(S().g(), ""); // expected-error {{constant expression}} expected-note {{in call to '&Temporaries::S()->g()'}}
866f4a2713aSLionel Sambuc static_assert(T(3).f() == 3, "");
867f4a2713aSLionel Sambuc static_assert(T(4).g() == 4, "");
868f4a2713aSLionel Sambuc 
f(const S & s)869f4a2713aSLionel Sambuc constexpr int f(const S &s) {
870f4a2713aSLionel Sambuc   return static_cast<const T&>(s).n;
871f4a2713aSLionel Sambuc }
872f4a2713aSLionel Sambuc constexpr int n = f(T(5));
873f4a2713aSLionel Sambuc static_assert(f(T(5)) == 5, "");
874f4a2713aSLionel Sambuc 
b(int n)875f4a2713aSLionel Sambuc constexpr bool b(int n) { return &n; }
876f4a2713aSLionel Sambuc static_assert(b(0), "");
877f4a2713aSLionel Sambuc 
878*0a6a1f1dSLionel Sambuc struct NonLiteral {
879*0a6a1f1dSLionel Sambuc   NonLiteral();
880*0a6a1f1dSLionel Sambuc   int f();
881*0a6a1f1dSLionel Sambuc };
882*0a6a1f1dSLionel Sambuc constexpr int k = NonLiteral().f(); // expected-error {{constant expression}} expected-note {{non-literal type 'Temporaries::NonLiteral'}}
883*0a6a1f1dSLionel Sambuc 
884f4a2713aSLionel Sambuc }
885f4a2713aSLionel Sambuc 
886f4a2713aSLionel Sambuc namespace Union {
887f4a2713aSLionel Sambuc 
888f4a2713aSLionel Sambuc union U {
889f4a2713aSLionel Sambuc   int a;
890f4a2713aSLionel Sambuc   int b;
891f4a2713aSLionel Sambuc };
892f4a2713aSLionel Sambuc 
893f4a2713aSLionel Sambuc constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } }; // expected-warning 4{{C99 feature}}
894f4a2713aSLionel Sambuc static_assert(u[0].a == 0, "");
895f4a2713aSLionel Sambuc static_assert(u[0].b, ""); // expected-error {{constant expression}} expected-note {{read of member 'b' of union with active member 'a'}}
896f4a2713aSLionel Sambuc static_assert(u[1].b == 1, "");
897f4a2713aSLionel Sambuc static_assert((&u[1].b)[1] == 2, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
898f4a2713aSLionel Sambuc static_assert(*(&(u[1].b) + 1 + 1) == 3, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element 2 of non-array object}}
899f4a2713aSLionel Sambuc static_assert((&(u[1]) + 1 + 1)->b == 3, "");
900f4a2713aSLionel Sambuc 
901f4a2713aSLionel Sambuc constexpr U v = {};
902f4a2713aSLionel Sambuc static_assert(v.a == 0, "");
903f4a2713aSLionel Sambuc 
904f4a2713aSLionel Sambuc union Empty {};
905f4a2713aSLionel Sambuc constexpr Empty e = {};
906f4a2713aSLionel Sambuc 
907f4a2713aSLionel Sambuc // Make sure we handle trivial copy constructors for unions.
908f4a2713aSLionel Sambuc constexpr U x = {42};
909f4a2713aSLionel Sambuc constexpr U y = x;
910f4a2713aSLionel Sambuc static_assert(y.a == 42, "");
911f4a2713aSLionel Sambuc static_assert(y.b == 42, ""); // expected-error {{constant expression}} expected-note {{'b' of union with active member 'a'}}
912f4a2713aSLionel Sambuc 
913f4a2713aSLionel Sambuc }
914f4a2713aSLionel Sambuc 
915f4a2713aSLionel Sambuc namespace MemberPointer {
916f4a2713aSLionel Sambuc   struct A {
AMemberPointer::A917f4a2713aSLionel Sambuc     constexpr A(int n) : n(n) {}
918f4a2713aSLionel Sambuc     int n;
fMemberPointer::A919f4a2713aSLionel Sambuc     constexpr int f() const { return n + 3; }
920f4a2713aSLionel Sambuc   };
921f4a2713aSLionel Sambuc   constexpr A a(7);
922f4a2713aSLionel Sambuc   static_assert(A(5).*&A::n == 5, "");
923f4a2713aSLionel Sambuc   static_assert((&a)->*&A::n == 7, "");
924f4a2713aSLionel Sambuc   static_assert((A(8).*&A::f)() == 11, "");
925f4a2713aSLionel Sambuc   static_assert(((&a)->*&A::f)() == 10, "");
926f4a2713aSLionel Sambuc 
927f4a2713aSLionel Sambuc   struct B : A {
BMemberPointer::B928f4a2713aSLionel Sambuc     constexpr B(int n, int m) : A(n), m(m) {}
929f4a2713aSLionel Sambuc     int m;
gMemberPointer::B930f4a2713aSLionel Sambuc     constexpr int g() const { return n + m + 1; }
931f4a2713aSLionel Sambuc   };
932f4a2713aSLionel Sambuc   constexpr B b(9, 13);
933f4a2713aSLionel Sambuc   static_assert(B(4, 11).*&A::n == 4, "");
934f4a2713aSLionel Sambuc   static_assert(B(4, 11).*&B::m == 11, "");
935f4a2713aSLionel Sambuc   static_assert(B(4, 11).*(int(A::*))&B::m == 11, "");
936f4a2713aSLionel Sambuc   static_assert((&b)->*&A::n == 9, "");
937f4a2713aSLionel Sambuc   static_assert((&b)->*&B::m == 13, "");
938f4a2713aSLionel Sambuc   static_assert((&b)->*(int(A::*))&B::m == 13, "");
939f4a2713aSLionel Sambuc   static_assert((B(4, 11).*&A::f)() == 7, "");
940f4a2713aSLionel Sambuc   static_assert((B(4, 11).*&B::g)() == 16, "");
941f4a2713aSLionel Sambuc   static_assert((B(4, 11).*(int(A::*)()const)&B::g)() == 16, "");
942f4a2713aSLionel Sambuc   static_assert(((&b)->*&A::f)() == 12, "");
943f4a2713aSLionel Sambuc   static_assert(((&b)->*&B::g)() == 23, "");
944f4a2713aSLionel Sambuc   static_assert(((&b)->*(int(A::*)()const)&B::g)() == 23, "");
945f4a2713aSLionel Sambuc 
946f4a2713aSLionel Sambuc   struct S {
SMemberPointer::S947f4a2713aSLionel Sambuc     constexpr S(int m, int n, int (S::*pf)() const, int S::*pn) :
948f4a2713aSLionel Sambuc       m(m), n(n), pf(pf), pn(pn) {}
SMemberPointer::S949f4a2713aSLionel Sambuc     constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {}
950f4a2713aSLionel Sambuc 
fMemberPointer::S951f4a2713aSLionel Sambuc     constexpr int f() const { return this->*pn; }
952f4a2713aSLionel Sambuc     virtual int g() const;
953f4a2713aSLionel Sambuc 
954f4a2713aSLionel Sambuc     int m, n;
955f4a2713aSLionel Sambuc     int (S::*pf)() const;
956f4a2713aSLionel Sambuc     int S::*pn;
957f4a2713aSLionel Sambuc   };
958f4a2713aSLionel Sambuc 
959f4a2713aSLionel Sambuc   constexpr int S::*pm = &S::m;
960f4a2713aSLionel Sambuc   constexpr int S::*pn = &S::n;
961f4a2713aSLionel Sambuc   constexpr int (S::*pf)() const = &S::f;
962f4a2713aSLionel Sambuc   constexpr int (S::*pg)() const = &S::g;
963f4a2713aSLionel Sambuc 
964f4a2713aSLionel Sambuc   constexpr S s(2, 5, &S::f, &S::m);
965f4a2713aSLionel Sambuc 
966f4a2713aSLionel Sambuc   static_assert((s.*&S::f)() == 2, "");
967f4a2713aSLionel Sambuc   static_assert((s.*s.pf)() == 2, "");
968f4a2713aSLionel Sambuc 
969f4a2713aSLionel Sambuc   static_assert(pf == &S::f, "");
970f4a2713aSLionel Sambuc   static_assert(pf == s.*&S::pf, "");
971f4a2713aSLionel Sambuc   static_assert(pm == &S::m, "");
972f4a2713aSLionel Sambuc   static_assert(pm != pn, "");
973f4a2713aSLionel Sambuc   static_assert(s.pn != pn, "");
974f4a2713aSLionel Sambuc   static_assert(s.pn == pm, "");
975f4a2713aSLionel Sambuc   static_assert(pg != nullptr, "");
976f4a2713aSLionel Sambuc   static_assert(pf != nullptr, "");
977f4a2713aSLionel Sambuc   static_assert((int S::*)nullptr == nullptr, "");
978f4a2713aSLionel Sambuc   static_assert(pg == pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}}
979f4a2713aSLionel Sambuc   static_assert(pf != pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}}
980f4a2713aSLionel Sambuc 
981f4a2713aSLionel Sambuc   template<int n> struct T : T<n-1> {};
982f4a2713aSLionel Sambuc   template<> struct T<0> { int n; };
983f4a2713aSLionel Sambuc   template<> struct T<30> : T<29> { int m; };
984f4a2713aSLionel Sambuc 
985f4a2713aSLionel Sambuc   T<17> t17;
986f4a2713aSLionel Sambuc   T<30> t30;
987f4a2713aSLionel Sambuc 
988f4a2713aSLionel Sambuc   constexpr int (T<10>::*deepn) = &T<0>::n;
989f4a2713aSLionel Sambuc   static_assert(&(t17.*deepn) == &t17.n, "");
990f4a2713aSLionel Sambuc   static_assert(deepn == &T<2>::n, "");
991f4a2713aSLionel Sambuc 
992f4a2713aSLionel Sambuc   constexpr int (T<15>::*deepm) = (int(T<10>::*))&T<30>::m;
993f4a2713aSLionel Sambuc   constexpr int *pbad = &(t17.*deepm); // expected-error {{constant expression}}
994f4a2713aSLionel Sambuc   static_assert(&(t30.*deepm) == &t30.m, "");
995f4a2713aSLionel Sambuc   static_assert(deepm == &T<50>::m, "");
996f4a2713aSLionel Sambuc   static_assert(deepm != deepn, "");
997f4a2713aSLionel Sambuc 
998f4a2713aSLionel Sambuc   constexpr T<5> *p17_5 = &t17;
999f4a2713aSLionel Sambuc   constexpr T<13> *p17_13 = (T<13>*)p17_5;
1000f4a2713aSLionel Sambuc   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>'}}
1001f4a2713aSLionel Sambuc   static_assert(&(p17_5->*(int(T<3>::*))deepn) == &t17.n, "");
1002f4a2713aSLionel Sambuc   static_assert(&(p17_13->*deepn) == &t17.n, "");
1003f4a2713aSLionel Sambuc   constexpr int *pbad2 = &(p17_13->*(int(T<9>::*))deepm); // expected-error {{constant expression}}
1004f4a2713aSLionel Sambuc 
1005f4a2713aSLionel Sambuc   constexpr T<5> *p30_5 = &t30;
1006f4a2713aSLionel Sambuc   constexpr T<23> *p30_23 = (T<23>*)p30_5;
1007f4a2713aSLionel Sambuc   constexpr T<13> *p30_13 = p30_23;
1008f4a2713aSLionel Sambuc   static_assert(&(p30_5->*(int(T<3>::*))deepn) == &t30.n, "");
1009f4a2713aSLionel Sambuc   static_assert(&(p30_13->*deepn) == &t30.n, "");
1010f4a2713aSLionel Sambuc   static_assert(&(p30_23->*deepn) == &t30.n, "");
1011f4a2713aSLionel Sambuc   static_assert(&(p30_5->*(int(T<2>::*))deepm) == &t30.m, "");
1012f4a2713aSLionel Sambuc   static_assert(&(((T<17>*)p30_13)->*deepm) == &t30.m, "");
1013f4a2713aSLionel Sambuc   static_assert(&(p30_23->*deepm) == &t30.m, "");
1014f4a2713aSLionel Sambuc 
1015f4a2713aSLionel Sambuc   struct Base { int n; };
1016f4a2713aSLionel Sambuc   template<int N> struct Mid : Base {};
1017f4a2713aSLionel Sambuc   struct Derived : Mid<0>, Mid<1> {};
1018f4a2713aSLionel Sambuc   static_assert(&Mid<0>::n == &Mid<1>::n, "");
1019f4a2713aSLionel Sambuc   static_assert((int Derived::*)(int Mid<0>::*)&Mid<0>::n !=
1020f4a2713aSLionel Sambuc                 (int Derived::*)(int Mid<1>::*)&Mid<1>::n, "");
1021f4a2713aSLionel Sambuc   static_assert(&Mid<0>::n == (int Mid<0>::*)&Base::n, "");
1022f4a2713aSLionel Sambuc }
1023f4a2713aSLionel Sambuc 
1024f4a2713aSLionel Sambuc namespace ArrayBaseDerived {
1025f4a2713aSLionel Sambuc 
1026f4a2713aSLionel Sambuc   struct Base {
BaseArrayBaseDerived::Base1027f4a2713aSLionel Sambuc     constexpr Base() {}
1028f4a2713aSLionel Sambuc     int n = 0;
1029f4a2713aSLionel Sambuc   };
1030f4a2713aSLionel Sambuc   struct Derived : Base {
DerivedArrayBaseDerived::Derived1031f4a2713aSLionel Sambuc     constexpr Derived() {}
fArrayBaseDerived::Derived1032f4a2713aSLionel Sambuc     constexpr const int *f() const { return &n; }
1033f4a2713aSLionel Sambuc   };
1034f4a2713aSLionel Sambuc 
1035f4a2713aSLionel Sambuc   constexpr Derived a[10];
1036f4a2713aSLionel Sambuc   constexpr Derived *pd3 = const_cast<Derived*>(&a[3]);
1037f4a2713aSLionel Sambuc   constexpr Base *pb3 = const_cast<Derived*>(&a[3]);
1038f4a2713aSLionel Sambuc   static_assert(pb3 == pd3, "");
1039f4a2713aSLionel Sambuc 
1040f4a2713aSLionel Sambuc   // pb3 does not point to an array element.
1041f4a2713aSLionel Sambuc   constexpr Base *pb4 = pb3 + 1; // ok, one-past-the-end pointer.
1042f4a2713aSLionel Sambuc   constexpr int pb4n = pb4->n; // expected-error {{constant expression}} expected-note {{cannot access field of pointer past the end}}
1043f4a2713aSLionel Sambuc   constexpr Base *err_pb5 = pb3 + 2; // expected-error {{constant expression}} expected-note {{cannot refer to element 2}} expected-note {{here}}
1044f4a2713aSLionel Sambuc   constexpr int err_pb5n = err_pb5->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb5' is not a constant expression}}
1045f4a2713aSLionel Sambuc   constexpr Base *err_pb2 = pb3 - 1; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} expected-note {{here}}
1046f4a2713aSLionel Sambuc   constexpr int err_pb2n = err_pb2->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb2'}}
1047f4a2713aSLionel Sambuc   constexpr Base *pb3a = pb4 - 1;
1048f4a2713aSLionel Sambuc 
1049f4a2713aSLionel Sambuc   // pb4 does not point to a Derived.
1050f4a2713aSLionel Sambuc   constexpr Derived *err_pd4 = (Derived*)pb4; // expected-error {{constant expression}} expected-note {{cannot access derived class of pointer past the end}}
1051f4a2713aSLionel Sambuc   constexpr Derived *pd3a = (Derived*)pb3a;
1052f4a2713aSLionel Sambuc   constexpr int pd3n = pd3a->n;
1053f4a2713aSLionel Sambuc 
1054f4a2713aSLionel Sambuc   // pd3a still points to the Derived array.
1055f4a2713aSLionel Sambuc   constexpr Derived *pd6 = pd3a + 3;
1056f4a2713aSLionel Sambuc   static_assert(pd6 == &a[6], "");
1057f4a2713aSLionel Sambuc   constexpr Derived *pd9 = pd6 + 3;
1058f4a2713aSLionel Sambuc   constexpr Derived *pd10 = pd6 + 4;
1059f4a2713aSLionel Sambuc   constexpr int pd9n = pd9->n; // ok
1060f4a2713aSLionel Sambuc   constexpr int err_pd10n = pd10->n; // expected-error {{constant expression}} expected-note {{cannot access base class of pointer past the end}}
1061f4a2713aSLionel Sambuc   constexpr int pd0n = pd10[-10].n;
1062f4a2713aSLionel Sambuc   constexpr int err_pdminus1n = pd10[-11].n; // expected-error {{constant expression}} expected-note {{cannot refer to element -1 of}}
1063f4a2713aSLionel Sambuc 
1064f4a2713aSLionel Sambuc   constexpr Base *pb9 = pd9;
1065f4a2713aSLionel Sambuc   constexpr const int *(Base::*pfb)() const =
1066f4a2713aSLionel Sambuc       static_cast<const int *(Base::*)() const>(&Derived::f);
1067f4a2713aSLionel Sambuc   static_assert((pb9->*pfb)() == &a[9].n, "");
1068f4a2713aSLionel Sambuc }
1069f4a2713aSLionel Sambuc 
1070f4a2713aSLionel Sambuc namespace Complex {
1071f4a2713aSLionel Sambuc 
1072f4a2713aSLionel Sambuc class complex {
1073f4a2713aSLionel Sambuc   int re, im;
1074f4a2713aSLionel Sambuc public:
complex(int re=0,int im=0)1075f4a2713aSLionel Sambuc   constexpr complex(int re = 0, int im = 0) : re(re), im(im) {}
complex(const complex & o)1076f4a2713aSLionel Sambuc   constexpr complex(const complex &o) : re(o.re), im(o.im) {}
operator -() const1077f4a2713aSLionel Sambuc   constexpr complex operator-() const { return complex(-re, -im); }
operator +(const complex & l,const complex & r)1078f4a2713aSLionel Sambuc   friend constexpr complex operator+(const complex &l, const complex &r) {
1079f4a2713aSLionel Sambuc     return complex(l.re + r.re, l.im + r.im);
1080f4a2713aSLionel Sambuc   }
operator -(const complex & l,const complex & r)1081f4a2713aSLionel Sambuc   friend constexpr complex operator-(const complex &l, const complex &r) {
1082f4a2713aSLionel Sambuc     return l + -r;
1083f4a2713aSLionel Sambuc   }
operator *(const complex & l,const complex & r)1084f4a2713aSLionel Sambuc   friend constexpr complex operator*(const complex &l, const complex &r) {
1085f4a2713aSLionel Sambuc     return complex(l.re * r.re - l.im * r.im, l.re * r.im + l.im * r.re);
1086f4a2713aSLionel Sambuc   }
operator ==(const complex & l,const complex & r)1087f4a2713aSLionel Sambuc   friend constexpr bool operator==(const complex &l, const complex &r) {
1088f4a2713aSLionel Sambuc     return l.re == r.re && l.im == r.im;
1089f4a2713aSLionel Sambuc   }
operator !=(const complex & r) const1090f4a2713aSLionel Sambuc   constexpr bool operator!=(const complex &r) const {
1091f4a2713aSLionel Sambuc     return re != r.re || im != r.im;
1092f4a2713aSLionel Sambuc   }
real() const1093f4a2713aSLionel Sambuc   constexpr int real() const { return re; }
imag() const1094f4a2713aSLionel Sambuc   constexpr int imag() const { return im; }
1095f4a2713aSLionel Sambuc };
1096f4a2713aSLionel Sambuc 
1097f4a2713aSLionel Sambuc constexpr complex i = complex(0, 1);
1098f4a2713aSLionel Sambuc constexpr complex k = (3 + 4*i) * (6 - 4*i);
1099f4a2713aSLionel Sambuc static_assert(complex(1,0).real() == 1, "");
1100f4a2713aSLionel Sambuc static_assert(complex(1,0).imag() == 0, "");
1101f4a2713aSLionel Sambuc static_assert(((complex)1).imag() == 0, "");
1102f4a2713aSLionel Sambuc static_assert(k.real() == 34, "");
1103f4a2713aSLionel Sambuc static_assert(k.imag() == 12, "");
1104f4a2713aSLionel Sambuc static_assert(k - 34 == 12*i, "");
1105f4a2713aSLionel Sambuc static_assert((complex)1 == complex(1), "");
1106f4a2713aSLionel Sambuc static_assert((complex)1 != complex(0, 1), "");
1107f4a2713aSLionel Sambuc static_assert(complex(1) == complex(1), "");
1108f4a2713aSLionel Sambuc static_assert(complex(1) != complex(0, 1), "");
makeComplex(int re,int im)1109f4a2713aSLionel Sambuc constexpr complex makeComplex(int re, int im) { return complex(re, im); }
1110f4a2713aSLionel Sambuc static_assert(makeComplex(1,0) == complex(1), "");
1111f4a2713aSLionel Sambuc static_assert(makeComplex(1,0) != complex(0, 1), "");
1112f4a2713aSLionel Sambuc 
1113f4a2713aSLionel Sambuc class complex_wrap : public complex {
1114f4a2713aSLionel Sambuc public:
complex_wrap(int re,int im=0)1115f4a2713aSLionel Sambuc   constexpr complex_wrap(int re, int im = 0) : complex(re, im) {}
complex_wrap(const complex_wrap & o)1116f4a2713aSLionel Sambuc   constexpr complex_wrap(const complex_wrap &o) : complex(o) {}
1117f4a2713aSLionel Sambuc };
1118f4a2713aSLionel Sambuc 
1119f4a2713aSLionel Sambuc static_assert((complex_wrap)1 == complex(1), "");
1120f4a2713aSLionel Sambuc static_assert((complex)1 != complex_wrap(0, 1), "");
1121f4a2713aSLionel Sambuc static_assert(complex(1) == complex_wrap(1), "");
1122f4a2713aSLionel Sambuc static_assert(complex_wrap(1) != complex(0, 1), "");
makeComplexWrap(int re,int im)1123f4a2713aSLionel Sambuc constexpr complex_wrap makeComplexWrap(int re, int im) {
1124f4a2713aSLionel Sambuc   return complex_wrap(re, im);
1125f4a2713aSLionel Sambuc }
1126f4a2713aSLionel Sambuc static_assert(makeComplexWrap(1,0) == complex(1), "");
1127f4a2713aSLionel Sambuc static_assert(makeComplexWrap(1,0) != complex(0, 1), "");
1128f4a2713aSLionel Sambuc 
1129f4a2713aSLionel Sambuc }
1130f4a2713aSLionel Sambuc 
1131f4a2713aSLionel Sambuc namespace PR11595 {
operator ==PR11595::A1132f4a2713aSLionel Sambuc   struct A { constexpr bool operator==(int x) const { return true; } };
1133f4a2713aSLionel Sambuc   struct B { B(); A& x; };
1134f4a2713aSLionel Sambuc   static_assert(B().x == 3, "");  // expected-error {{constant expression}} expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
1135f4a2713aSLionel Sambuc 
f(int k)1136f4a2713aSLionel Sambuc   constexpr bool f(int k) { // expected-error {{constexpr function never produces a constant expression}}
1137f4a2713aSLionel Sambuc     return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}}
1138f4a2713aSLionel Sambuc   }
1139f4a2713aSLionel Sambuc }
1140f4a2713aSLionel Sambuc 
1141f4a2713aSLionel Sambuc namespace ExprWithCleanups {
1142f4a2713aSLionel Sambuc   struct A { A(); ~A(); int get(); };
get(bool FromA)1143f4a2713aSLionel Sambuc   constexpr int get(bool FromA) { return FromA ? A().get() : 1; }
1144f4a2713aSLionel Sambuc   constexpr int n = get(false);
1145f4a2713aSLionel Sambuc }
1146f4a2713aSLionel Sambuc 
1147f4a2713aSLionel Sambuc namespace Volatile {
1148f4a2713aSLionel Sambuc 
1149f4a2713aSLionel Sambuc volatile constexpr int n1 = 0; // expected-note {{here}}
1150f4a2713aSLionel Sambuc volatile const int n2 = 0; // expected-note {{here}}
1151f4a2713aSLionel Sambuc int n3 = 37; // expected-note {{declared here}}
1152f4a2713aSLionel Sambuc 
1153f4a2713aSLionel Sambuc constexpr int m1 = n1; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
1154f4a2713aSLionel Sambuc constexpr int m2 = n2; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}}
1155f4a2713aSLionel Sambuc constexpr int m1b = const_cast<const int&>(n1); // expected-error {{constant expression}} expected-note {{read of volatile object 'n1'}}
1156f4a2713aSLionel Sambuc constexpr int m2b = const_cast<const int&>(n2); // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}}
1157f4a2713aSLionel Sambuc 
1158f4a2713aSLionel Sambuc struct T { int n; };
1159f4a2713aSLionel Sambuc const T t = { 42 }; // expected-note {{declared here}}
1160f4a2713aSLionel Sambuc 
f(volatile int && r)1161f4a2713aSLionel Sambuc constexpr int f(volatile int &&r) {
1162f4a2713aSLionel Sambuc   return r; // expected-note {{read of volatile-qualified type 'volatile int'}}
1163f4a2713aSLionel Sambuc }
g(volatile int && r)1164f4a2713aSLionel Sambuc constexpr int g(volatile int &&r) {
1165f4a2713aSLionel Sambuc   return const_cast<int&>(r); // expected-note {{read of volatile temporary is not allowed in a constant expression}}
1166f4a2713aSLionel Sambuc }
1167f4a2713aSLionel Sambuc struct S {
1168f4a2713aSLionel Sambuc   int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}}
1169f4a2713aSLionel Sambuc   int k : g(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'g(0)'}}
1170f4a2713aSLionel Sambuc   int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}}
1171f4a2713aSLionel Sambuc   int m : t.n; // expected-error {{constant expression}} expected-note {{read of non-constexpr variable}}
1172f4a2713aSLionel Sambuc };
1173f4a2713aSLionel Sambuc 
1174f4a2713aSLionel Sambuc }
1175f4a2713aSLionel Sambuc 
1176f4a2713aSLionel Sambuc namespace ExternConstexpr {
1177f4a2713aSLionel Sambuc   extern constexpr int n = 0;
1178f4a2713aSLionel Sambuc   extern constexpr int m; // expected-error {{constexpr variable declaration must be a definition}}
f()1179f4a2713aSLionel Sambuc   void f() {
1180f4a2713aSLionel Sambuc     extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}}
1181f4a2713aSLionel Sambuc     constexpr int j = 0;
1182*0a6a1f1dSLionel Sambuc     constexpr int k; // expected-error {{default initialization of an object of const type}} expected-note{{add an explicit initializer to initialize 'k'}}
1183f4a2713aSLionel Sambuc   }
1184f4a2713aSLionel Sambuc }
1185f4a2713aSLionel Sambuc 
1186f4a2713aSLionel Sambuc namespace ComplexConstexpr {
1187f4a2713aSLionel Sambuc   constexpr _Complex float test1 = {};
1188f4a2713aSLionel Sambuc   constexpr _Complex float test2 = {1};
1189f4a2713aSLionel Sambuc   constexpr _Complex double test3 = {1,2};
1190f4a2713aSLionel Sambuc   constexpr _Complex int test4 = {4};
1191f4a2713aSLionel Sambuc   constexpr _Complex int test5 = 4;
1192f4a2713aSLionel Sambuc   constexpr _Complex int test6 = {5,6};
1193f4a2713aSLionel Sambuc   typedef _Complex float fcomplex;
1194f4a2713aSLionel Sambuc   constexpr fcomplex test7 = fcomplex();
1195f4a2713aSLionel Sambuc 
1196f4a2713aSLionel Sambuc   constexpr const double &t2r = __real test3;
1197f4a2713aSLionel Sambuc   constexpr const double &t2i = __imag test3;
1198f4a2713aSLionel Sambuc   static_assert(&t2r + 1 == &t2i, "");
1199f4a2713aSLionel Sambuc   static_assert(t2r == 1.0, "");
1200f4a2713aSLionel Sambuc   static_assert(t2i == 2.0, "");
1201f4a2713aSLionel Sambuc   constexpr const double *t2p = &t2r;
1202f4a2713aSLionel Sambuc   static_assert(t2p[-1] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element -1 of array of 2 elements}}
1203f4a2713aSLionel Sambuc   static_assert(t2p[0] == 1.0, "");
1204f4a2713aSLionel Sambuc   static_assert(t2p[1] == 2.0, "");
1205f4a2713aSLionel Sambuc   static_assert(t2p[2] == 0.0, ""); // expected-error {{constant expr}} expected-note {{one-past-the-end pointer}}
1206f4a2713aSLionel Sambuc   static_assert(t2p[3] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element 3 of array of 2 elements}}
1207f4a2713aSLionel Sambuc   constexpr _Complex float *p = 0;
1208f4a2713aSLionel Sambuc   constexpr float pr = __real *p; // expected-error {{constant expr}} expected-note {{cannot access real component of null}}
1209f4a2713aSLionel Sambuc   constexpr float pi = __imag *p; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of null}}
1210f4a2713aSLionel Sambuc   constexpr const _Complex double *q = &test3 + 1;
1211f4a2713aSLionel Sambuc   constexpr double qr = __real *q; // expected-error {{constant expr}} expected-note {{cannot access real component of pointer past the end}}
1212f4a2713aSLionel Sambuc   constexpr double qi = __imag *q; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of pointer past the end}}
1213f4a2713aSLionel Sambuc 
1214f4a2713aSLionel Sambuc   static_assert(__real test6 == 5, "");
1215f4a2713aSLionel Sambuc   static_assert(__imag test6 == 6, "");
1216f4a2713aSLionel Sambuc   static_assert(&__imag test6 == &__real test6 + 1, "");
1217f4a2713aSLionel Sambuc }
1218f4a2713aSLionel Sambuc 
1219f4a2713aSLionel Sambuc // _Atomic(T) is exactly like T for the purposes of constant expression
1220f4a2713aSLionel Sambuc // evaluation..
1221f4a2713aSLionel Sambuc namespace Atomic {
1222f4a2713aSLionel Sambuc   constexpr _Atomic int n = 3;
1223f4a2713aSLionel Sambuc 
1224f4a2713aSLionel Sambuc   struct S { _Atomic(double) d; };
1225f4a2713aSLionel Sambuc   constexpr S s = { 0.5 };
1226f4a2713aSLionel Sambuc   constexpr double d1 = s.d;
1227f4a2713aSLionel Sambuc   constexpr double d2 = n;
1228f4a2713aSLionel Sambuc   constexpr _Atomic double d3 = n;
1229f4a2713aSLionel Sambuc 
1230f4a2713aSLionel Sambuc   constexpr _Atomic(int) n2 = d3;
1231f4a2713aSLionel Sambuc   static_assert(d1 == 0.5, "");
1232f4a2713aSLionel Sambuc   static_assert(d3 == 3.0, "");
1233f4a2713aSLionel Sambuc 
1234f4a2713aSLionel Sambuc   namespace PR16056 {
1235f4a2713aSLionel Sambuc     struct TestVar {
1236f4a2713aSLionel Sambuc       _Atomic(int) value;
TestVarAtomic::PR16056::TestVar1237f4a2713aSLionel Sambuc       constexpr TestVar(int value) : value(value) {}
1238f4a2713aSLionel Sambuc     };
1239f4a2713aSLionel Sambuc     constexpr TestVar testVar{-1};
1240f4a2713aSLionel Sambuc     static_assert(testVar.value == -1, "");
1241f4a2713aSLionel Sambuc   }
1242f4a2713aSLionel Sambuc }
1243f4a2713aSLionel Sambuc 
1244f4a2713aSLionel Sambuc namespace InstantiateCaseStmt {
f()1245f4a2713aSLionel Sambuc   template<int x> constexpr int f() { return x; }
g(int c)1246f4a2713aSLionel Sambuc   template<int x> int g(int c) { switch(c) { case f<x>(): return 1; } return 0; }
gg(int c)1247f4a2713aSLionel Sambuc   int gg(int c) { return g<4>(c); }
1248f4a2713aSLionel Sambuc }
1249f4a2713aSLionel Sambuc 
1250f4a2713aSLionel Sambuc namespace ConvertedConstantExpr {
1251f4a2713aSLionel Sambuc   extern int &m;
1252f4a2713aSLionel Sambuc   extern int &n;
1253f4a2713aSLionel Sambuc 
1254f4a2713aSLionel Sambuc   constexpr int k = 4;
1255f4a2713aSLionel Sambuc   int &m = const_cast<int&>(k);
1256f4a2713aSLionel Sambuc 
1257f4a2713aSLionel Sambuc   // If we have nothing more interesting to say, ensure we don't produce a
1258f4a2713aSLionel Sambuc   // useless note and instead just point to the non-constant subexpression.
1259f4a2713aSLionel Sambuc   enum class E {
1260f4a2713aSLionel Sambuc     em = m,
1261f4a2713aSLionel Sambuc     en = n, // expected-error {{not a constant expression}}
1262f4a2713aSLionel Sambuc     eo = (m +
1263f4a2713aSLionel Sambuc           n // expected-error {{not a constant expression}}
1264f4a2713aSLionel Sambuc           ),
1265f4a2713aSLionel Sambuc     eq = reinterpret_cast<int>((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}}
1266f4a2713aSLionel Sambuc   };
1267f4a2713aSLionel Sambuc }
1268f4a2713aSLionel Sambuc 
1269f4a2713aSLionel Sambuc namespace IndirectField {
1270f4a2713aSLionel Sambuc   struct S {
1271f4a2713aSLionel Sambuc     struct { // expected-warning {{GNU extension}}
1272f4a2713aSLionel Sambuc       union { // expected-warning {{declared in an anonymous struct}}
1273f4a2713aSLionel Sambuc         struct { // expected-warning {{GNU extension}} expected-warning {{declared in an anonymous union}}
1274f4a2713aSLionel Sambuc           int a;
1275f4a2713aSLionel Sambuc           int b;
1276f4a2713aSLionel Sambuc         };
1277f4a2713aSLionel Sambuc         int c;
1278f4a2713aSLionel Sambuc       };
1279f4a2713aSLionel Sambuc       int d;
1280f4a2713aSLionel Sambuc     };
1281f4a2713aSLionel Sambuc     union {
1282f4a2713aSLionel Sambuc       int e;
1283f4a2713aSLionel Sambuc       int f;
1284f4a2713aSLionel Sambuc     };
SIndirectField::S1285f4a2713aSLionel Sambuc     constexpr S(int a, int b, int d, int e) : a(a), b(b), d(d), e(e) {}
SIndirectField::S1286f4a2713aSLionel Sambuc     constexpr S(int c, int d, int f) : c(c), d(d), f(f) {}
1287f4a2713aSLionel Sambuc   };
1288f4a2713aSLionel Sambuc 
1289f4a2713aSLionel Sambuc   constexpr S s1(1, 2, 3, 4);
1290f4a2713aSLionel Sambuc   constexpr S s2(5, 6, 7);
1291f4a2713aSLionel Sambuc 
1292f4a2713aSLionel Sambuc   // FIXME: The diagnostics here do a very poor job of explaining which unnamed
1293f4a2713aSLionel Sambuc   // member is active and which is requested.
1294f4a2713aSLionel Sambuc   static_assert(s1.a == 1, "");
1295f4a2713aSLionel Sambuc   static_assert(s1.b == 2, "");
1296f4a2713aSLionel Sambuc   static_assert(s1.c == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1297f4a2713aSLionel Sambuc   static_assert(s1.d == 3, "");
1298f4a2713aSLionel Sambuc   static_assert(s1.e == 4, "");
1299f4a2713aSLionel Sambuc   static_assert(s1.f == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1300f4a2713aSLionel Sambuc 
1301f4a2713aSLionel Sambuc   static_assert(s2.a == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1302f4a2713aSLionel Sambuc   static_assert(s2.b == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1303f4a2713aSLionel Sambuc   static_assert(s2.c == 5, "");
1304f4a2713aSLionel Sambuc   static_assert(s2.d == 6, "");
1305f4a2713aSLionel Sambuc   static_assert(s2.e == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}}
1306f4a2713aSLionel Sambuc   static_assert(s2.f == 7, "");
1307f4a2713aSLionel Sambuc }
1308f4a2713aSLionel Sambuc 
1309f4a2713aSLionel Sambuc // DR1405: don't allow reading mutable members in constant expressions.
1310f4a2713aSLionel Sambuc namespace MutableMembers {
1311f4a2713aSLionel Sambuc   struct MM {
1312f4a2713aSLionel Sambuc     mutable int n; // expected-note 3{{declared here}}
1313f4a2713aSLionel Sambuc   } constexpr mm = { 4 };
1314f4a2713aSLionel Sambuc   constexpr int mmn = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
1315f4a2713aSLionel Sambuc   int x = (mm.n = 1, 3);
1316f4a2713aSLionel Sambuc   constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
1317f4a2713aSLionel Sambuc 
1318f4a2713aSLionel Sambuc   // Here's one reason why allowing this would be a disaster...
1319f4a2713aSLionel Sambuc   template<int n> struct Id { int k = n; };
f()1320f4a2713aSLionel Sambuc   int f() {
1321f4a2713aSLionel Sambuc     constexpr MM m = { 0 };
1322f4a2713aSLionel Sambuc     ++m.n;
1323f4a2713aSLionel Sambuc     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}}
1324f4a2713aSLionel Sambuc   }
1325f4a2713aSLionel Sambuc 
1326f4a2713aSLionel Sambuc   struct A { int n; };
1327f4a2713aSLionel Sambuc   struct B { mutable A a; }; // expected-note {{here}}
1328f4a2713aSLionel Sambuc   struct C { B b; };
1329f4a2713aSLionel Sambuc   constexpr C c[3] = {};
1330f4a2713aSLionel Sambuc   constexpr int k = c[1].b.a.n; // expected-error {{constant expression}} expected-note {{mutable}}
1331*0a6a1f1dSLionel Sambuc 
1332*0a6a1f1dSLionel Sambuc   struct D { int x; mutable int y; }; // expected-note {{here}}
1333*0a6a1f1dSLionel Sambuc   constexpr D d1 = { 1, 2 };
1334*0a6a1f1dSLionel Sambuc   int l = ++d1.y;
1335*0a6a1f1dSLionel Sambuc   constexpr D d2 = d1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}}
1336*0a6a1f1dSLionel Sambuc 
1337*0a6a1f1dSLionel Sambuc   struct E {
1338*0a6a1f1dSLionel Sambuc     union {
1339*0a6a1f1dSLionel Sambuc       int a;
1340*0a6a1f1dSLionel Sambuc       mutable int b; // expected-note {{here}}
1341*0a6a1f1dSLionel Sambuc     };
1342*0a6a1f1dSLionel Sambuc   };
1343*0a6a1f1dSLionel Sambuc   constexpr E e1 = {{1}};
1344*0a6a1f1dSLionel Sambuc   constexpr E e2 = e1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}}
1345*0a6a1f1dSLionel Sambuc 
1346*0a6a1f1dSLionel Sambuc   struct F {
1347*0a6a1f1dSLionel Sambuc     union U { };
1348*0a6a1f1dSLionel Sambuc     mutable U u;
1349*0a6a1f1dSLionel Sambuc     struct X { };
1350*0a6a1f1dSLionel Sambuc     mutable X x;
1351*0a6a1f1dSLionel Sambuc     struct Y : X { X x; U u; };
1352*0a6a1f1dSLionel Sambuc     mutable Y y;
1353*0a6a1f1dSLionel Sambuc     int n;
1354*0a6a1f1dSLionel Sambuc   };
1355*0a6a1f1dSLionel Sambuc   // This is OK; we don't actually read any mutable state here.
1356*0a6a1f1dSLionel Sambuc   constexpr F f1 = {};
1357*0a6a1f1dSLionel Sambuc   constexpr F f2 = f1;
1358*0a6a1f1dSLionel Sambuc 
1359*0a6a1f1dSLionel Sambuc   struct G {
1360*0a6a1f1dSLionel Sambuc     struct X {};
1361*0a6a1f1dSLionel Sambuc     union U { X a; };
1362*0a6a1f1dSLionel Sambuc     mutable U u; // expected-note {{here}}
1363*0a6a1f1dSLionel Sambuc   };
1364*0a6a1f1dSLionel Sambuc   constexpr G g1 = {};
1365*0a6a1f1dSLionel Sambuc   constexpr G g2 = g1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}}
1366*0a6a1f1dSLionel Sambuc   constexpr G::U gu1 = {};
1367*0a6a1f1dSLionel Sambuc   constexpr G::U gu2 = gu1;
1368*0a6a1f1dSLionel Sambuc 
1369*0a6a1f1dSLionel Sambuc   union H {
1370*0a6a1f1dSLionel Sambuc     mutable G::X gx; // expected-note {{here}}
1371*0a6a1f1dSLionel Sambuc   };
1372*0a6a1f1dSLionel Sambuc   constexpr H h1 = {};
1373*0a6a1f1dSLionel Sambuc   constexpr H h2 = h1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}}
1374f4a2713aSLionel Sambuc }
1375f4a2713aSLionel Sambuc 
1376f4a2713aSLionel Sambuc namespace Fold {
1377f4a2713aSLionel Sambuc 
1378f4a2713aSLionel Sambuc   // This macro forces its argument to be constant-folded, even if it's not
1379f4a2713aSLionel Sambuc   // otherwise a constant expression.
1380f4a2713aSLionel Sambuc   #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
1381f4a2713aSLionel Sambuc 
1382f4a2713aSLionel Sambuc   constexpr int n = (int)(char*)123; // expected-error {{constant expression}} expected-note {{reinterpret_cast}}
1383f4a2713aSLionel Sambuc   constexpr int m = fold((int)(char*)123); // ok
1384f4a2713aSLionel Sambuc   static_assert(m == 123, "");
1385f4a2713aSLionel Sambuc 
1386f4a2713aSLionel Sambuc   #undef fold
1387f4a2713aSLionel Sambuc 
1388f4a2713aSLionel Sambuc }
1389f4a2713aSLionel Sambuc 
1390f4a2713aSLionel Sambuc namespace DR1454 {
1391f4a2713aSLionel Sambuc 
f(const int & n)1392f4a2713aSLionel Sambuc constexpr const int &f(const int &n) { return n; }
1393f4a2713aSLionel Sambuc constexpr int k1 = f(0); // ok
1394f4a2713aSLionel Sambuc 
1395f4a2713aSLionel Sambuc struct Wrap {
1396f4a2713aSLionel Sambuc   const int &value;
1397f4a2713aSLionel Sambuc };
g(const Wrap & w)1398f4a2713aSLionel Sambuc constexpr const Wrap &g(const Wrap &w) { return w; }
1399f4a2713aSLionel Sambuc constexpr int k2 = g({0}).value; // ok
1400f4a2713aSLionel Sambuc 
1401f4a2713aSLionel Sambuc // The temporary here has static storage duration, so we can bind a constexpr
1402f4a2713aSLionel Sambuc // reference to it.
1403f4a2713aSLionel Sambuc constexpr const int &i = 1;
1404f4a2713aSLionel Sambuc constexpr const int j = i;
1405f4a2713aSLionel Sambuc static_assert(j == 1, "");
1406f4a2713aSLionel Sambuc 
1407f4a2713aSLionel Sambuc // The temporary here is not const, so it can't be read outside the expression
1408f4a2713aSLionel Sambuc // in which it was created (per the C++14 rules, which we use to avoid a C++11
1409f4a2713aSLionel Sambuc // defect).
1410f4a2713aSLionel Sambuc constexpr int &&k = 1; // expected-note {{temporary created here}}
1411f4a2713aSLionel Sambuc constexpr const int l = k; // expected-error {{constant expression}} expected-note {{read of temporary}}
1412f4a2713aSLionel Sambuc 
f()1413f4a2713aSLionel Sambuc void f() {
1414f4a2713aSLionel Sambuc   // The temporary here has automatic storage duration, so we can't bind a
1415f4a2713aSLionel Sambuc   // constexpr reference to it.
1416f4a2713aSLionel Sambuc   constexpr const int &i = 1; // expected-error {{constant expression}} expected-note 2{{temporary}}
1417f4a2713aSLionel Sambuc }
1418f4a2713aSLionel Sambuc 
1419f4a2713aSLionel Sambuc }
1420f4a2713aSLionel Sambuc 
1421f4a2713aSLionel Sambuc namespace RecursiveOpaqueExpr {
1422f4a2713aSLionel Sambuc   template<typename Iter>
LastNonzero(Iter p,Iter q)1423f4a2713aSLionel Sambuc   constexpr auto LastNonzero(Iter p, Iter q) -> decltype(+*p) {
1424f4a2713aSLionel Sambuc     return p != q ? (LastNonzero(p+1, q) ?: *p) : 0; // expected-warning {{GNU}}
1425f4a2713aSLionel Sambuc   }
1426f4a2713aSLionel Sambuc 
1427f4a2713aSLionel Sambuc   constexpr int arr1[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 0 };
1428f4a2713aSLionel Sambuc   static_assert(LastNonzero(begin(arr1), end(arr1)) == 4, "");
1429f4a2713aSLionel Sambuc 
1430f4a2713aSLionel Sambuc   constexpr int arr2[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 5 };
1431f4a2713aSLionel Sambuc   static_assert(LastNonzero(begin(arr2), end(arr2)) == 5, "");
1432f4a2713aSLionel Sambuc 
1433f4a2713aSLionel Sambuc   constexpr int arr3[] = {
1434f4a2713aSLionel Sambuc     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,
1435f4a2713aSLionel Sambuc     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,
1436f4a2713aSLionel Sambuc     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,
1437f4a2713aSLionel Sambuc     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,
1438f4a2713aSLionel Sambuc     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,
1439f4a2713aSLionel Sambuc     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,
1440f4a2713aSLionel Sambuc     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,
1441f4a2713aSLionel Sambuc     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 };
1442f4a2713aSLionel Sambuc   static_assert(LastNonzero(begin(arr3), end(arr3)) == 2, "");
1443f4a2713aSLionel Sambuc }
1444f4a2713aSLionel Sambuc 
1445f4a2713aSLionel Sambuc namespace VLASizeof {
1446f4a2713aSLionel Sambuc 
f(int k)1447f4a2713aSLionel Sambuc   void f(int k) {
1448f4a2713aSLionel Sambuc     int arr[k]; // expected-warning {{C99}}
1449f4a2713aSLionel Sambuc     constexpr int n = 1 +
1450f4a2713aSLionel Sambuc         sizeof(arr) // expected-error {{constant expression}}
1451f4a2713aSLionel Sambuc         * 3;
1452f4a2713aSLionel Sambuc   }
1453f4a2713aSLionel Sambuc }
1454f4a2713aSLionel Sambuc 
1455f4a2713aSLionel Sambuc namespace CompoundLiteral {
1456f4a2713aSLionel Sambuc   // FIXME:
1457f4a2713aSLionel Sambuc   // We don't model the semantics of this correctly: the compound literal is
1458f4a2713aSLionel Sambuc   // represented as a prvalue in the AST, but actually behaves like an lvalue.
1459f4a2713aSLionel Sambuc   // We treat the compound literal as a temporary and refuse to produce a
1460f4a2713aSLionel Sambuc   // pointer to it. This is OK: we're not required to treat this as a constant
1461f4a2713aSLionel Sambuc   // in C++, and in C we model compound literals as lvalues.
1462f4a2713aSLionel Sambuc   constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}}
1463f4a2713aSLionel Sambuc }
1464f4a2713aSLionel Sambuc 
1465f4a2713aSLionel Sambuc namespace Vector {
1466f4a2713aSLionel Sambuc   typedef int __attribute__((vector_size(16))) VI4;
f(int n)1467f4a2713aSLionel Sambuc   constexpr VI4 f(int n) {
1468f4a2713aSLionel Sambuc     return VI4 { n * 3, n + 4, n - 5, n / 6 };
1469f4a2713aSLionel Sambuc   }
1470f4a2713aSLionel Sambuc   constexpr auto v1 = f(10);
1471f4a2713aSLionel Sambuc 
1472f4a2713aSLionel Sambuc   typedef double __attribute__((vector_size(32))) VD4;
g(int n)1473f4a2713aSLionel Sambuc   constexpr VD4 g(int n) {
1474f4a2713aSLionel Sambuc     return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 }; // expected-warning {{C99}}
1475f4a2713aSLionel Sambuc   }
1476f4a2713aSLionel Sambuc   constexpr auto v2 = g(4);
1477f4a2713aSLionel Sambuc }
1478f4a2713aSLionel Sambuc 
1479f4a2713aSLionel Sambuc // PR12626, redux
1480f4a2713aSLionel Sambuc namespace InvalidClasses {
test0()1481f4a2713aSLionel Sambuc   void test0() {
1482f4a2713aSLionel Sambuc     struct X; // expected-note {{forward declaration}}
1483f4a2713aSLionel Sambuc     struct Y { bool b; X x; }; // expected-error {{field has incomplete type}}
1484f4a2713aSLionel Sambuc     Y y;
1485f4a2713aSLionel Sambuc     auto& b = y.b;
1486f4a2713aSLionel Sambuc   }
1487f4a2713aSLionel Sambuc }
1488f4a2713aSLionel Sambuc 
1489f4a2713aSLionel Sambuc namespace NamespaceAlias {
f()1490f4a2713aSLionel Sambuc   constexpr int f() {
1491*0a6a1f1dSLionel Sambuc     namespace NS = NamespaceAlias; // expected-warning {{use of this statement in a constexpr function is a C++14 extension}}
1492f4a2713aSLionel Sambuc     return &NS::f != nullptr;
1493f4a2713aSLionel Sambuc   }
1494f4a2713aSLionel Sambuc }
1495f4a2713aSLionel Sambuc 
1496f4a2713aSLionel Sambuc // Constructors can be implicitly constexpr, even for a non-literal type.
1497f4a2713aSLionel Sambuc namespace ImplicitConstexpr {
1498f4a2713aSLionel Sambuc   struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}}
1499f4a2713aSLionel Sambuc   struct R { constexpr R() noexcept; constexpr R(const R&) noexcept; constexpr R(R&&) noexcept; ~R() noexcept; };
1500f4a2713aSLionel Sambuc   struct S { R r; }; // expected-note 3{{here}}
1501f4a2713aSLionel Sambuc   struct T { T(const T&) noexcept; T(T &&) noexcept; ~T() noexcept; };
1502f4a2713aSLionel Sambuc   struct U { T t; }; // expected-note 3{{here}}
1503f4a2713aSLionel Sambuc   static_assert(!__is_literal_type(Q), "");
1504f4a2713aSLionel Sambuc   static_assert(!__is_literal_type(R), "");
1505f4a2713aSLionel Sambuc   static_assert(!__is_literal_type(S), "");
1506f4a2713aSLionel Sambuc   static_assert(!__is_literal_type(T), "");
1507f4a2713aSLionel Sambuc   static_assert(!__is_literal_type(U), "");
1508f4a2713aSLionel Sambuc   struct Test {
1509f4a2713aSLionel Sambuc     friend Q::Q() noexcept; // expected-error {{follows constexpr}}
1510f4a2713aSLionel Sambuc     friend Q::Q(Q&&) noexcept; // expected-error {{follows constexpr}}
1511f4a2713aSLionel Sambuc     friend Q::Q(const Q&) noexcept; // expected-error {{follows constexpr}}
1512f4a2713aSLionel Sambuc     friend S::S() noexcept; // expected-error {{follows constexpr}}
1513f4a2713aSLionel Sambuc     friend S::S(S&&) noexcept; // expected-error {{follows constexpr}}
1514f4a2713aSLionel Sambuc     friend S::S(const S&) noexcept; // expected-error {{follows constexpr}}
1515f4a2713aSLionel Sambuc     friend constexpr U::U() noexcept; // expected-error {{follows non-constexpr}}
1516f4a2713aSLionel Sambuc     friend constexpr U::U(U&&) noexcept; // expected-error {{follows non-constexpr}}
1517f4a2713aSLionel Sambuc     friend constexpr U::U(const U&) noexcept; // expected-error {{follows non-constexpr}}
1518f4a2713aSLionel Sambuc   };
1519f4a2713aSLionel Sambuc }
1520f4a2713aSLionel Sambuc 
1521f4a2713aSLionel Sambuc // Indirectly test that an implicit lvalue to xvalue conversion performed for
1522f4a2713aSLionel Sambuc // an NRVO move operation isn't implemented as CK_LValueToRValue.
1523f4a2713aSLionel Sambuc namespace PR12826 {
1524f4a2713aSLionel Sambuc   struct Foo {};
id(Foo x)1525f4a2713aSLionel Sambuc   constexpr Foo id(Foo x) { return x; }
1526f4a2713aSLionel Sambuc   constexpr Foo res(id(Foo()));
1527f4a2713aSLionel Sambuc }
1528f4a2713aSLionel Sambuc 
1529f4a2713aSLionel Sambuc namespace PR13273 {
1530f4a2713aSLionel Sambuc   struct U {
1531f4a2713aSLionel Sambuc     int t;
1532f4a2713aSLionel Sambuc     U() = default;
1533f4a2713aSLionel Sambuc   };
1534f4a2713aSLionel Sambuc 
1535f4a2713aSLionel Sambuc   struct S : U {
1536f4a2713aSLionel Sambuc     S() = default;
1537f4a2713aSLionel Sambuc   };
1538f4a2713aSLionel Sambuc 
1539f4a2713aSLionel Sambuc   // S's default constructor isn't constexpr, because U's default constructor
1540f4a2713aSLionel Sambuc   // doesn't initialize 't', but it's trivial, so value-initialization doesn't
1541f4a2713aSLionel Sambuc   // actually call it.
1542f4a2713aSLionel Sambuc   static_assert(S{}.t == 0, "");
1543f4a2713aSLionel Sambuc }
1544f4a2713aSLionel Sambuc 
1545f4a2713aSLionel Sambuc namespace PR12670 {
1546f4a2713aSLionel Sambuc   struct S {
SPR12670::S1547f4a2713aSLionel Sambuc     constexpr S(int a0) : m(a0) {}
SPR12670::S1548f4a2713aSLionel Sambuc     constexpr S() : m(6) {}
1549f4a2713aSLionel Sambuc     int m;
1550f4a2713aSLionel Sambuc   };
1551f4a2713aSLionel Sambuc   constexpr S x[3] = { {4}, 5 };
1552f4a2713aSLionel Sambuc   static_assert(x[0].m == 4, "");
1553f4a2713aSLionel Sambuc   static_assert(x[1].m == 5, "");
1554f4a2713aSLionel Sambuc   static_assert(x[2].m == 6, "");
1555f4a2713aSLionel Sambuc }
1556f4a2713aSLionel Sambuc 
1557f4a2713aSLionel Sambuc // Indirectly test that an implicit lvalue-to-rvalue conversion is performed
1558f4a2713aSLionel Sambuc // when a conditional operator has one argument of type void and where the other
1559f4a2713aSLionel Sambuc // is a glvalue of class type.
1560f4a2713aSLionel Sambuc namespace ConditionalLValToRVal {
1561f4a2713aSLionel Sambuc   struct A {
AConditionalLValToRVal::A1562f4a2713aSLionel Sambuc     constexpr A(int a) : v(a) {}
1563f4a2713aSLionel Sambuc     int v;
1564f4a2713aSLionel Sambuc   };
1565f4a2713aSLionel Sambuc 
f(const A & a)1566f4a2713aSLionel Sambuc   constexpr A f(const A &a) {
1567f4a2713aSLionel Sambuc     return a.v == 0 ? throw a : a;
1568f4a2713aSLionel Sambuc   }
1569f4a2713aSLionel Sambuc 
1570f4a2713aSLionel Sambuc   constexpr A a(4);
1571f4a2713aSLionel Sambuc   static_assert(f(a).v == 4, "");
1572f4a2713aSLionel Sambuc }
1573f4a2713aSLionel Sambuc 
1574f4a2713aSLionel Sambuc namespace TLS {
1575f4a2713aSLionel Sambuc   __thread int n;
1576f4a2713aSLionel Sambuc   int m;
1577f4a2713aSLionel Sambuc 
1578f4a2713aSLionel Sambuc   constexpr bool b = &n == &n;
1579f4a2713aSLionel Sambuc 
1580f4a2713aSLionel Sambuc   constexpr int *p = &n; // expected-error{{constexpr variable 'p' must be initialized by a constant expression}}
1581f4a2713aSLionel Sambuc 
f()1582f4a2713aSLionel Sambuc   constexpr int *f() { return &n; }
1583f4a2713aSLionel Sambuc   constexpr int *q = f(); // expected-error{{constexpr variable 'q' must be initialized by a constant expression}}
1584f4a2713aSLionel Sambuc   constexpr bool c = f() == f();
1585f4a2713aSLionel Sambuc 
g()1586f4a2713aSLionel Sambuc   constexpr int *g() { return &m; }
1587f4a2713aSLionel Sambuc   constexpr int *r = g();
1588f4a2713aSLionel Sambuc }
1589f4a2713aSLionel Sambuc 
1590f4a2713aSLionel Sambuc namespace Void {
f()1591f4a2713aSLionel Sambuc   constexpr void f() { return; } // expected-error{{constexpr function's return type 'void' is not a literal type}}
1592f4a2713aSLionel Sambuc 
1593f4a2713aSLionel Sambuc   void assert_failed(const char *msg, const char *file, int line); // expected-note {{declared here}}
1594f4a2713aSLionel Sambuc #define ASSERT(expr) ((expr) ? static_cast<void>(0) : assert_failed(#expr, __FILE__, __LINE__))
1595f4a2713aSLionel Sambuc   template<typename T, size_t S>
get(T (& a)[S],size_t k)1596f4a2713aSLionel Sambuc   constexpr T get(T (&a)[S], size_t k) {
1597f4a2713aSLionel Sambuc     return ASSERT(k > 0 && k < S), a[k]; // expected-note{{non-constexpr function 'assert_failed'}}
1598f4a2713aSLionel Sambuc   }
1599f4a2713aSLionel Sambuc #undef ASSERT
1600f4a2713aSLionel Sambuc   template int get(int (&a)[4], size_t);
1601f4a2713aSLionel Sambuc   constexpr int arr[] = { 4, 1, 2, 3, 4 };
1602f4a2713aSLionel Sambuc   static_assert(get(arr, 1) == 1, "");
1603f4a2713aSLionel Sambuc   static_assert(get(arr, 4) == 4, "");
1604f4a2713aSLionel Sambuc   static_assert(get(arr, 0) == 4, ""); // expected-error{{not an integral constant expression}} \
1605f4a2713aSLionel Sambuc   // expected-note{{in call to 'get(arr, 0)'}}
1606f4a2713aSLionel Sambuc }
1607f4a2713aSLionel Sambuc 
1608f4a2713aSLionel Sambuc namespace std { struct type_info; }
1609f4a2713aSLionel Sambuc 
1610f4a2713aSLionel Sambuc namespace TypeId {
1611f4a2713aSLionel Sambuc   struct A { virtual ~A(); };
1612f4a2713aSLionel Sambuc   A f();
1613f4a2713aSLionel Sambuc   A &g();
1614f4a2713aSLionel Sambuc   constexpr auto &x = typeid(f());
1615f4a2713aSLionel Sambuc   constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \
1616*0a6a1f1dSLionel Sambuc   // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}} \
1617*0a6a1f1dSLionel Sambuc   // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
1618f4a2713aSLionel Sambuc }
1619f4a2713aSLionel Sambuc 
1620f4a2713aSLionel Sambuc namespace PR14203 {
1621f4a2713aSLionel Sambuc   struct duration {
durationPR14203::duration1622f4a2713aSLionel Sambuc     constexpr duration() {}
operator intPR14203::duration1623f4a2713aSLionel Sambuc     constexpr operator int() const { return 0; }
1624f4a2713aSLionel Sambuc   };
f()1625f4a2713aSLionel Sambuc   template<typename T> void f() {
1626f4a2713aSLionel Sambuc     // If we want to evaluate this at the point of the template definition, we
1627f4a2713aSLionel Sambuc     // need to trigger the implicit definition of the move constructor at that
1628f4a2713aSLionel Sambuc     // point.
1629f4a2713aSLionel Sambuc     // FIXME: C++ does not permit us to implicitly define it at the appropriate
1630f4a2713aSLionel Sambuc     // times, since it is only allowed to be implicitly defined when it is
1631f4a2713aSLionel Sambuc     // odr-used.
1632f4a2713aSLionel Sambuc     constexpr duration d = duration();
1633f4a2713aSLionel Sambuc   }
1634f4a2713aSLionel Sambuc   // FIXME: It's unclear whether this is valid. On the one hand, we're not
1635f4a2713aSLionel Sambuc   // allowed to generate a move constructor. On the other hand, if we did,
1636f4a2713aSLionel Sambuc   // this would be a constant expression. For now, we generate a move
1637f4a2713aSLionel Sambuc   // constructor here.
1638f4a2713aSLionel Sambuc   int n = sizeof(short{duration(duration())});
1639f4a2713aSLionel Sambuc }
1640f4a2713aSLionel Sambuc 
1641f4a2713aSLionel Sambuc namespace ArrayEltInit {
1642f4a2713aSLionel Sambuc   struct A {
AArrayEltInit::A1643f4a2713aSLionel Sambuc     constexpr A() : p(&p) {}
1644f4a2713aSLionel Sambuc     void *p;
1645f4a2713aSLionel Sambuc   };
1646f4a2713aSLionel Sambuc   constexpr A a[10];
1647f4a2713aSLionel Sambuc   static_assert(a[0].p == &a[0].p, "");
1648f4a2713aSLionel Sambuc   static_assert(a[9].p == &a[9].p, "");
1649f4a2713aSLionel Sambuc   static_assert(a[0].p != &a[9].p, "");
1650f4a2713aSLionel Sambuc   static_assert(a[9].p != &a[0].p, "");
1651f4a2713aSLionel Sambuc 
1652f4a2713aSLionel Sambuc   constexpr A b[10] = {};
1653f4a2713aSLionel Sambuc   static_assert(b[0].p == &b[0].p, "");
1654f4a2713aSLionel Sambuc   static_assert(b[9].p == &b[9].p, "");
1655f4a2713aSLionel Sambuc   static_assert(b[0].p != &b[9].p, "");
1656f4a2713aSLionel Sambuc   static_assert(b[9].p != &b[0].p, "");
1657f4a2713aSLionel Sambuc }
1658f4a2713aSLionel Sambuc 
1659f4a2713aSLionel Sambuc namespace PR15884 {
1660f4a2713aSLionel Sambuc   struct S {};
f()1661f4a2713aSLionel Sambuc   constexpr S f() { return {}; }
1662f4a2713aSLionel Sambuc   constexpr S *p = &f();
1663f4a2713aSLionel Sambuc   // expected-error@-1 {{taking the address of a temporary}}
1664f4a2713aSLionel Sambuc   // expected-error@-2 {{constexpr variable 'p' must be initialized by a constant expression}}
1665f4a2713aSLionel Sambuc   // expected-note@-3 {{pointer to temporary is not a constant expression}}
1666f4a2713aSLionel Sambuc   // expected-note@-4 {{temporary created here}}
1667f4a2713aSLionel Sambuc }
1668f4a2713aSLionel Sambuc 
1669f4a2713aSLionel Sambuc namespace AfterError {
1670f4a2713aSLionel Sambuc   // FIXME: Suppress the 'no return statements' diagnostic if the body is invalid.
error()1671f4a2713aSLionel Sambuc   constexpr int error() { // expected-error {{no return statement}}
1672f4a2713aSLionel Sambuc     return foobar; // expected-error {{undeclared identifier}}
1673f4a2713aSLionel Sambuc   }
1674f4a2713aSLionel Sambuc   constexpr int k = error(); // expected-error {{must be initialized by a constant expression}}
1675f4a2713aSLionel Sambuc }
1676f4a2713aSLionel Sambuc 
1677f4a2713aSLionel Sambuc namespace std {
1678f4a2713aSLionel Sambuc   typedef decltype(sizeof(int)) size_t;
1679f4a2713aSLionel Sambuc 
1680f4a2713aSLionel Sambuc   template <class _E>
1681f4a2713aSLionel Sambuc   class initializer_list
1682f4a2713aSLionel Sambuc   {
1683f4a2713aSLionel Sambuc     const _E* __begin_;
1684f4a2713aSLionel Sambuc     size_t    __size_;
1685f4a2713aSLionel Sambuc 
initializer_list(const _E * __b,size_t __s)1686f4a2713aSLionel Sambuc     constexpr initializer_list(const _E* __b, size_t __s)
1687f4a2713aSLionel Sambuc       : __begin_(__b),
1688f4a2713aSLionel Sambuc         __size_(__s)
1689f4a2713aSLionel Sambuc     {}
1690f4a2713aSLionel Sambuc 
1691f4a2713aSLionel Sambuc   public:
1692f4a2713aSLionel Sambuc     typedef _E        value_type;
1693f4a2713aSLionel Sambuc     typedef const _E& reference;
1694f4a2713aSLionel Sambuc     typedef const _E& const_reference;
1695f4a2713aSLionel Sambuc     typedef size_t    size_type;
1696f4a2713aSLionel Sambuc 
1697f4a2713aSLionel Sambuc     typedef const _E* iterator;
1698f4a2713aSLionel Sambuc     typedef const _E* const_iterator;
1699f4a2713aSLionel Sambuc 
initializer_list()1700f4a2713aSLionel Sambuc     constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
1701f4a2713aSLionel Sambuc 
size() const1702f4a2713aSLionel Sambuc     constexpr size_t    size()  const {return __size_;}
begin() const1703f4a2713aSLionel Sambuc     constexpr const _E* begin() const {return __begin_;}
end() const1704f4a2713aSLionel Sambuc     constexpr const _E* end()   const {return __begin_ + __size_;}
1705f4a2713aSLionel Sambuc   };
1706f4a2713aSLionel Sambuc }
1707f4a2713aSLionel Sambuc 
1708f4a2713aSLionel Sambuc namespace InitializerList {
sum(const int * b,const int * e)1709f4a2713aSLionel Sambuc   constexpr int sum(const int *b, const int *e) {
1710f4a2713aSLionel Sambuc     return b != e ? *b + sum(b+1, e) : 0;
1711f4a2713aSLionel Sambuc   }
sum(std::initializer_list<int> ints)1712f4a2713aSLionel Sambuc   constexpr int sum(std::initializer_list<int> ints) {
1713f4a2713aSLionel Sambuc     return sum(ints.begin(), ints.end());
1714f4a2713aSLionel Sambuc   }
1715f4a2713aSLionel Sambuc   static_assert(sum({1, 2, 3, 4, 5}) == 15, "");
1716*0a6a1f1dSLionel Sambuc 
1717*0a6a1f1dSLionel Sambuc   static_assert(*std::initializer_list<int>{1, 2, 3}.begin() == 1, "");
1718*0a6a1f1dSLionel Sambuc   static_assert(std::initializer_list<int>{1, 2, 3}.begin()[2] == 3, "");
1719f4a2713aSLionel Sambuc }
1720f4a2713aSLionel Sambuc 
1721f4a2713aSLionel Sambuc namespace StmtExpr {
1722f4a2713aSLionel Sambuc   struct A { int k; };
f()1723f4a2713aSLionel Sambuc   void f() {
1724f4a2713aSLionel Sambuc     static_assert(({ const int x = 5; x * 3; }) == 15, ""); // expected-warning {{extension}}
1725f4a2713aSLionel Sambuc     constexpr auto a = ({ A(); }); // expected-warning {{extension}}
1726f4a2713aSLionel Sambuc   }
g(int k)1727f4a2713aSLionel Sambuc   constexpr int g(int k) {
1728f4a2713aSLionel Sambuc     return ({ // expected-warning {{extension}}
1729f4a2713aSLionel Sambuc       const int x = k;
1730f4a2713aSLionel Sambuc       x * x;
1731f4a2713aSLionel Sambuc     });
1732f4a2713aSLionel Sambuc   }
1733f4a2713aSLionel Sambuc   static_assert(g(123) == 15129, "");
h()1734f4a2713aSLionel Sambuc   constexpr int h() { // expected-error {{never produces a constant}}
1735f4a2713aSLionel Sambuc     return ({ // expected-warning {{extension}}
1736f4a2713aSLionel Sambuc       return 0; // expected-note {{not supported}}
1737f4a2713aSLionel Sambuc       1;
1738f4a2713aSLionel Sambuc     });
1739f4a2713aSLionel Sambuc   }
1740f4a2713aSLionel Sambuc }
1741f4a2713aSLionel Sambuc 
1742f4a2713aSLionel Sambuc namespace VirtualFromBase {
1743f4a2713aSLionel Sambuc   struct S1 {
1744f4a2713aSLionel Sambuc     virtual int f() const;
1745f4a2713aSLionel Sambuc   };
1746f4a2713aSLionel Sambuc   struct S2 {
1747f4a2713aSLionel Sambuc     virtual int f();
1748f4a2713aSLionel Sambuc   };
1749f4a2713aSLionel Sambuc   template <typename T> struct X : T {
XVirtualFromBase::X1750f4a2713aSLionel Sambuc     constexpr X() {}
1751f4a2713aSLionel Sambuc     double d = 0.0;
fVirtualFromBase::X1752*0a6a1f1dSLionel Sambuc     constexpr int f() { return sizeof(T); } // expected-warning {{will not be implicitly 'const' in C++14}}
1753f4a2713aSLionel Sambuc   };
1754f4a2713aSLionel Sambuc 
1755f4a2713aSLionel Sambuc   // Virtual f(), not OK.
1756f4a2713aSLionel Sambuc   constexpr X<X<S1>> xxs1;
1757f4a2713aSLionel Sambuc   constexpr X<S1> *p = const_cast<X<X<S1>>*>(&xxs1);
1758f4a2713aSLionel Sambuc   static_assert(p->f() == sizeof(X<S1>), ""); // expected-error {{constant expression}} expected-note {{virtual function call}}
1759f4a2713aSLionel Sambuc 
1760f4a2713aSLionel Sambuc   // Non-virtual f(), OK.
1761f4a2713aSLionel Sambuc   constexpr X<X<S2>> xxs2;
1762f4a2713aSLionel Sambuc   constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2);
1763f4a2713aSLionel Sambuc   static_assert(q->f() == sizeof(S2), "");
1764f4a2713aSLionel Sambuc }
1765f4a2713aSLionel Sambuc 
1766f4a2713aSLionel Sambuc namespace ConstexprConstructorRecovery {
1767f4a2713aSLionel Sambuc   class X {
1768f4a2713aSLionel Sambuc   public:
1769f4a2713aSLionel Sambuc       enum E : short {
1770f4a2713aSLionel Sambuc           headers = 0x1,
1771f4a2713aSLionel Sambuc           middlefile = 0x2,
1772f4a2713aSLionel Sambuc           choices = 0x4
1773f4a2713aSLionel Sambuc       };
X()1774f4a2713aSLionel Sambuc       constexpr X() noexcept {};
1775f4a2713aSLionel Sambuc   protected:
1776f4a2713aSLionel Sambuc       E val{0}; // expected-error {{cannot initialize a member subobject of type 'ConstexprConstructorRecovery::X::E' with an rvalue of type 'int'}}
1777f4a2713aSLionel Sambuc   };
1778f4a2713aSLionel Sambuc   constexpr X x{};
1779f4a2713aSLionel Sambuc }
1780f4a2713aSLionel Sambuc 
1781f4a2713aSLionel Sambuc namespace Lifetime {
f()1782f4a2713aSLionel Sambuc   void f() {
1783f4a2713aSLionel Sambuc     constexpr int &n = n; // expected-error {{constant expression}} expected-note {{use of reference outside its lifetime}} expected-warning {{not yet bound to a value}}
1784f4a2713aSLionel Sambuc     constexpr int m = m; // expected-error {{constant expression}} expected-note {{read of object outside its lifetime}}
1785f4a2713aSLionel Sambuc   }
1786f4a2713aSLionel Sambuc 
get(int && n)1787f4a2713aSLionel Sambuc   constexpr int &get(int &&n) { return n; }
1788f4a2713aSLionel Sambuc   struct S {
1789f4a2713aSLionel Sambuc     int &&r; // expected-note 2{{declared here}}
1790f4a2713aSLionel Sambuc     int &s;
1791f4a2713aSLionel Sambuc     int t;
SLifetime::S1792f4a2713aSLionel Sambuc     constexpr S() : r(0), s(get(0)), t(r) {} // expected-warning {{temporary}}
SLifetime::S1793f4a2713aSLionel Sambuc     constexpr S(int) : r(0), s(get(0)), t(s) {} // expected-warning {{temporary}} expected-note {{read of object outside its lifetime}}
1794f4a2713aSLionel Sambuc   };
1795f4a2713aSLionel Sambuc   constexpr int k1 = S().t; // ok, int is lifetime-extended to end of constructor
1796f4a2713aSLionel Sambuc   constexpr int k2 = S(0).t; // expected-error {{constant expression}} expected-note {{in call}}
1797f4a2713aSLionel Sambuc }
1798f4a2713aSLionel Sambuc 
1799f4a2713aSLionel Sambuc namespace Bitfields {
1800f4a2713aSLionel Sambuc   struct A {
1801f4a2713aSLionel Sambuc     bool b : 1;
1802f4a2713aSLionel Sambuc     unsigned u : 5;
1803f4a2713aSLionel Sambuc     int n : 5;
1804f4a2713aSLionel Sambuc     bool b2 : 3;
1805f4a2713aSLionel Sambuc     unsigned u2 : 74; // expected-warning {{exceeds the size of its type}}
1806f4a2713aSLionel Sambuc     int n2 : 81; // expected-warning {{exceeds the size of its type}}
1807f4a2713aSLionel Sambuc   };
1808f4a2713aSLionel Sambuc 
1809f4a2713aSLionel Sambuc   constexpr A a = { false, 33, 31, false, 0xffffffff, 0x7fffffff }; // expected-warning 2{{truncation}}
1810f4a2713aSLionel Sambuc   static_assert(a.b == 0 && a.u == 1 && a.n == -1 && a.b2 == 0 &&
1811f4a2713aSLionel Sambuc                 a.u2 + 1 == 0 && a.n2 == 0x7fffffff,
1812f4a2713aSLionel Sambuc                 "bad truncation of bitfield values");
1813f4a2713aSLionel Sambuc 
1814f4a2713aSLionel Sambuc   struct B {
1815f4a2713aSLionel Sambuc     int n : 3;
BBitfields::B1816f4a2713aSLionel Sambuc     constexpr B(int k) : n(k) {}
1817f4a2713aSLionel Sambuc   };
1818f4a2713aSLionel Sambuc   static_assert(B(3).n == 3, "");
1819f4a2713aSLionel Sambuc   static_assert(B(4).n == -4, "");
1820f4a2713aSLionel Sambuc   static_assert(B(7).n == -1, "");
1821f4a2713aSLionel Sambuc   static_assert(B(8).n == 0, "");
1822f4a2713aSLionel Sambuc   static_assert(B(-1).n == -1, "");
1823f4a2713aSLionel Sambuc   static_assert(B(-8889).n == -1, "");
1824f4a2713aSLionel Sambuc 
1825f4a2713aSLionel Sambuc   namespace PR16755 {
1826f4a2713aSLionel Sambuc     struct X {
1827f4a2713aSLionel Sambuc       int x : 1;
fBitfields::PR16755::X1828f4a2713aSLionel Sambuc       constexpr static int f(int x) {
1829f4a2713aSLionel Sambuc         return X{x}.x;
1830f4a2713aSLionel Sambuc       }
1831f4a2713aSLionel Sambuc     };
1832f4a2713aSLionel Sambuc     static_assert(X::f(3) == -1, "3 should truncate to -1");
1833f4a2713aSLionel Sambuc   }
1834f4a2713aSLionel Sambuc }
1835f4a2713aSLionel Sambuc 
1836f4a2713aSLionel Sambuc namespace ZeroSizeTypes {
1837f4a2713aSLionel Sambuc   constexpr int (*p1)[0] = 0, (*p2)[0] = 0;
1838f4a2713aSLionel Sambuc   constexpr int k = p2 - p1;
1839f4a2713aSLionel Sambuc   // expected-error@-1 {{constexpr variable 'k' must be initialized by a constant expression}}
1840f4a2713aSLionel Sambuc   // expected-note@-2 {{subtraction of pointers to type 'int [0]' of zero size}}
1841f4a2713aSLionel Sambuc 
1842f4a2713aSLionel Sambuc   int arr[5][0];
f()1843f4a2713aSLionel Sambuc   constexpr int f() { // expected-error {{never produces a constant expression}}
1844f4a2713aSLionel Sambuc     return &arr[3] - &arr[0]; // expected-note {{subtraction of pointers to type 'int [0]' of zero size}}
1845f4a2713aSLionel Sambuc   }
1846f4a2713aSLionel Sambuc }
1847f4a2713aSLionel Sambuc 
1848f4a2713aSLionel Sambuc namespace BadDefaultInit {
1849f4a2713aSLionel Sambuc   template<int N> struct X { static const int n = N; };
1850f4a2713aSLionel Sambuc 
1851*0a6a1f1dSLionel Sambuc   struct A {
1852*0a6a1f1dSLionel Sambuc     int k = // expected-error {{cannot use defaulted default constructor of 'A' within the class outside of member functions because 'k' has an initializer}}
1853*0a6a1f1dSLionel Sambuc         X<A().k>::n; // expected-error {{not a constant expression}} expected-note {{implicit default constructor for 'BadDefaultInit::A' first required here}}
1854f4a2713aSLionel Sambuc   };
1855f4a2713aSLionel Sambuc 
1856f4a2713aSLionel Sambuc   // FIXME: The "constexpr constructor must initialize all members" diagnostic
1857f4a2713aSLionel Sambuc   // here is bogus (we discard the k(k) initializer because the parameter 'k'
1858f4a2713aSLionel Sambuc   // has been marked invalid).
1859f4a2713aSLionel Sambuc   struct B { // expected-note 2{{candidate}}
BBadDefaultInit::B1860f4a2713aSLionel Sambuc     constexpr B( // expected-error {{must initialize all members}} expected-note {{candidate}}
1861f4a2713aSLionel Sambuc         int k = X<B().k>::n) : // expected-error {{no matching constructor}}
1862f4a2713aSLionel Sambuc       k(k) {}
1863f4a2713aSLionel Sambuc     int k; // expected-note {{not initialized}}
1864f4a2713aSLionel Sambuc   };
1865f4a2713aSLionel Sambuc }
1866f4a2713aSLionel Sambuc 
1867f4a2713aSLionel Sambuc namespace NeverConstantTwoWays {
1868f4a2713aSLionel Sambuc   // If we see something non-constant but foldable followed by something
1869f4a2713aSLionel Sambuc   // non-constant and not foldable, we want the first diagnostic, not the
1870f4a2713aSLionel Sambuc   // second.
f(int n)1871f4a2713aSLionel Sambuc   constexpr int f(int n) { // expected-error {{never produces a constant expression}}
1872f4a2713aSLionel Sambuc     return (int *)(long)&n == &n ? // expected-note {{reinterpret_cast}}
1873f4a2713aSLionel Sambuc         1 / 0 : // expected-warning {{division by zero}}
1874f4a2713aSLionel Sambuc         0;
1875f4a2713aSLionel Sambuc   }
1876f4a2713aSLionel Sambuc 
1877f4a2713aSLionel Sambuc   // FIXME: We should diagnose the cast to long here, not the division by zero.
1878f4a2713aSLionel Sambuc   constexpr int n = // expected-error {{must be initialized by a constant expression}}
1879f4a2713aSLionel Sambuc       (int *)(long)&n == &n ?
1880f4a2713aSLionel Sambuc         1 / 0 : // expected-warning {{division by zero}} expected-note {{division by zero}}
1881f4a2713aSLionel Sambuc         0;
1882f4a2713aSLionel Sambuc }
1883f4a2713aSLionel Sambuc 
1884f4a2713aSLionel Sambuc namespace PR17800 {
1885f4a2713aSLionel Sambuc   struct A {
operator ()PR17800::A1886f4a2713aSLionel Sambuc     constexpr int operator()() const { return 0; }
1887f4a2713aSLionel Sambuc   };
sink(T...)1888f4a2713aSLionel Sambuc   template <typename ...T> constexpr int sink(T ...) {
1889f4a2713aSLionel Sambuc     return 0;
1890f4a2713aSLionel Sambuc   }
run()1891f4a2713aSLionel Sambuc   template <int ...N> constexpr int run() {
1892f4a2713aSLionel Sambuc     return sink(A()() + N ...);
1893f4a2713aSLionel Sambuc   }
1894f4a2713aSLionel Sambuc   constexpr int k = run<1, 2, 3>();
1895f4a2713aSLionel Sambuc }
1896f4a2713aSLionel Sambuc 
1897f4a2713aSLionel Sambuc namespace BuiltinStrlen {
1898f4a2713aSLionel Sambuc   constexpr const char *a = "foo\0quux";
1899f4a2713aSLionel Sambuc   constexpr char b[] = "foo\0quux";
f()1900f4a2713aSLionel Sambuc   constexpr int f() { return 'u'; }
1901f4a2713aSLionel Sambuc   constexpr char c[] = { 'f', 'o', 'o', 0, 'q', f(), 'u', 'x', 0 };
1902f4a2713aSLionel Sambuc 
1903f4a2713aSLionel Sambuc   static_assert(__builtin_strlen("foo") == 3, "");
1904f4a2713aSLionel Sambuc   static_assert(__builtin_strlen("foo\0quux") == 3, "");
1905f4a2713aSLionel Sambuc   static_assert(__builtin_strlen("foo\0quux" + 4) == 4, "");
1906f4a2713aSLionel Sambuc 
check(const char * p)1907f4a2713aSLionel Sambuc   constexpr bool check(const char *p) {
1908f4a2713aSLionel Sambuc     return __builtin_strlen(p) == 3 &&
1909f4a2713aSLionel Sambuc            __builtin_strlen(p + 1) == 2 &&
1910f4a2713aSLionel Sambuc            __builtin_strlen(p + 2) == 1 &&
1911f4a2713aSLionel Sambuc            __builtin_strlen(p + 3) == 0 &&
1912f4a2713aSLionel Sambuc            __builtin_strlen(p + 4) == 4 &&
1913f4a2713aSLionel Sambuc            __builtin_strlen(p + 5) == 3 &&
1914f4a2713aSLionel Sambuc            __builtin_strlen(p + 6) == 2 &&
1915f4a2713aSLionel Sambuc            __builtin_strlen(p + 7) == 1 &&
1916f4a2713aSLionel Sambuc            __builtin_strlen(p + 8) == 0;
1917f4a2713aSLionel Sambuc   }
1918f4a2713aSLionel Sambuc 
1919f4a2713aSLionel Sambuc   static_assert(check(a), "");
1920f4a2713aSLionel Sambuc   static_assert(check(b), "");
1921f4a2713aSLionel Sambuc   static_assert(check(c), "");
1922f4a2713aSLionel Sambuc 
1923f4a2713aSLionel Sambuc   constexpr int over1 = __builtin_strlen(a + 9); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
1924f4a2713aSLionel Sambuc   constexpr int over2 = __builtin_strlen(b + 9); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
1925f4a2713aSLionel Sambuc   constexpr int over3 = __builtin_strlen(c + 9); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
1926f4a2713aSLionel Sambuc 
1927f4a2713aSLionel Sambuc   constexpr int under1 = __builtin_strlen(a - 1); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
1928f4a2713aSLionel Sambuc   constexpr int under2 = __builtin_strlen(b - 1); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
1929f4a2713aSLionel Sambuc   constexpr int under3 = __builtin_strlen(c - 1); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
1930f4a2713aSLionel Sambuc 
1931f4a2713aSLionel Sambuc   // FIXME: The diagnostic here could be better.
1932f4a2713aSLionel Sambuc   constexpr char d[] = { 'f', 'o', 'o' }; // no nul terminator.
1933f4a2713aSLionel Sambuc   constexpr int bad = __builtin_strlen(d); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
1934f4a2713aSLionel Sambuc }
1935*0a6a1f1dSLionel Sambuc 
1936*0a6a1f1dSLionel Sambuc namespace PR19010 {
1937*0a6a1f1dSLionel Sambuc   struct Empty {};
1938*0a6a1f1dSLionel Sambuc   struct Empty2 : Empty {};
1939*0a6a1f1dSLionel Sambuc   struct Test : Empty2 {
TestPR19010::Test1940*0a6a1f1dSLionel Sambuc     constexpr Test() {}
1941*0a6a1f1dSLionel Sambuc     Empty2 array[2];
1942*0a6a1f1dSLionel Sambuc   };
test()1943*0a6a1f1dSLionel Sambuc   void test() { constexpr Test t; }
1944*0a6a1f1dSLionel Sambuc }
1945*0a6a1f1dSLionel Sambuc 
PR21327(int a,int b)1946*0a6a1f1dSLionel Sambuc void PR21327(int a, int b) {
1947*0a6a1f1dSLionel Sambuc   static_assert(&a + 1 != &b, ""); // expected-error {{constant expression}}
1948*0a6a1f1dSLionel Sambuc }
1949*0a6a1f1dSLionel Sambuc 
1950*0a6a1f1dSLionel Sambuc namespace EmptyClass {
1951*0a6a1f1dSLionel Sambuc   struct E1 {} e1;
1952*0a6a1f1dSLionel Sambuc   union E2 {} e2; // expected-note {{here}}
1953*0a6a1f1dSLionel Sambuc   struct E3 : E1 {} e3;
1954*0a6a1f1dSLionel Sambuc 
1955*0a6a1f1dSLionel Sambuc   // The defaulted copy constructor for an empty class does not read any
1956*0a6a1f1dSLionel Sambuc   // members. The defaulted copy constructor for an empty union reads the
1957*0a6a1f1dSLionel Sambuc   // object representation.
1958*0a6a1f1dSLionel Sambuc   constexpr E1 e1b(e1);
1959*0a6a1f1dSLionel Sambuc   constexpr E2 e2b(e2); // expected-error {{constant expression}} expected-note{{read of non-const}} expected-note {{in call}}
1960*0a6a1f1dSLionel Sambuc   constexpr E3 e3b(e3);
1961*0a6a1f1dSLionel Sambuc }
1962*0a6a1f1dSLionel Sambuc 
1963*0a6a1f1dSLionel Sambuc namespace PR21786 {
1964*0a6a1f1dSLionel Sambuc   extern void (*start[])();
1965*0a6a1f1dSLionel Sambuc   extern void (*end[])();
1966*0a6a1f1dSLionel Sambuc   static_assert(&start != &end, ""); // expected-error {{constant expression}}
1967*0a6a1f1dSLionel Sambuc   static_assert(&start != nullptr, "");
1968*0a6a1f1dSLionel Sambuc 
1969*0a6a1f1dSLionel Sambuc   struct Foo;
1970*0a6a1f1dSLionel Sambuc   struct Bar {
1971*0a6a1f1dSLionel Sambuc     static const Foo x;
1972*0a6a1f1dSLionel Sambuc     static const Foo y;
1973*0a6a1f1dSLionel Sambuc   };
1974*0a6a1f1dSLionel Sambuc   static_assert(&Bar::x != nullptr, "");
1975*0a6a1f1dSLionel Sambuc   static_assert(&Bar::x != &Bar::y, "");
1976*0a6a1f1dSLionel Sambuc }
1977*0a6a1f1dSLionel Sambuc 
1978*0a6a1f1dSLionel Sambuc namespace PR21859 {
Fun()1979*0a6a1f1dSLionel Sambuc   constexpr int Fun() { return; } // expected-error {{non-void constexpr function 'Fun' should return a value}}
1980*0a6a1f1dSLionel Sambuc   constexpr int Var = Fun(); // expected-error {{constexpr variable 'Var' must be initialized by a constant expression}}
1981*0a6a1f1dSLionel Sambuc }
1982*0a6a1f1dSLionel Sambuc 
1983*0a6a1f1dSLionel Sambuc struct InvalidRedef {
1984*0a6a1f1dSLionel Sambuc   int f; // expected-note{{previous definition is here}}
1985*0a6a1f1dSLionel Sambuc   constexpr int f(void); // expected-error{{redefinition of 'f'}} expected-warning{{will not be implicitly 'const'}}
1986*0a6a1f1dSLionel Sambuc };
1987