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