constant-expression-cxx11.cpp revision f050d2445ed75569ccfe0740caa900403d2ce3b3
1// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment 2 3namespace StaticAssertFoldTest { 4 5int x; 6static_assert(++x, "test"); // expected-error {{not an integral constant expression}} 7static_assert(false, "test"); // expected-error {{test}} 8 9} 10 11typedef decltype(sizeof(char)) size_t; 12 13template<typename T> constexpr T id(const T &t) { return t; } 14template<typename T> constexpr T min(const T &a, const T &b) { 15 return a < b ? a : b; 16} 17template<typename T> constexpr T max(const T &a, const T &b) { 18 return a < b ? b : a; 19} 20template<typename T, size_t N> constexpr T *begin(T (&xs)[N]) { return xs; } 21template<typename T, size_t N> constexpr T *end(T (&xs)[N]) { return xs + N; } 22 23struct MemberZero { 24 constexpr int zero() const { return 0; } 25}; 26 27namespace DerivedToVBaseCast { 28 29 struct U { int n; }; 30 struct V : U { int n; }; 31 struct A : virtual V { int n; }; 32 struct Aa { int n; }; 33 struct B : virtual A, Aa {}; 34 struct C : virtual A, Aa {}; 35 struct D : B, C {}; 36 37 D d; 38 constexpr B *p = &d; 39 constexpr C *q = &d; 40 41 static_assert((void*)p != (void*)q, ""); 42 static_assert((A*)p == (A*)q, ""); 43 static_assert((Aa*)p != (Aa*)q, ""); 44 45 constexpr B &pp = d; 46 constexpr C &qq = d; 47 static_assert((void*)&pp != (void*)&qq, ""); 48 static_assert(&(A&)pp == &(A&)qq, ""); 49 static_assert(&(Aa&)pp != &(Aa&)qq, ""); 50 51 constexpr V *v = p; 52 constexpr V *w = q; 53 constexpr V *x = (A*)p; 54 static_assert(v == w, ""); 55 static_assert(v == x, ""); 56 57 static_assert((U*)&d == p, ""); 58 static_assert((U*)&d == q, ""); 59 static_assert((U*)&d == v, ""); 60 static_assert((U*)&d == w, ""); 61 static_assert((U*)&d == x, ""); 62 63 struct X {}; 64 struct Y1 : virtual X {}; 65 struct Y2 : X {}; 66 struct Z : Y1, Y2 {}; 67 Z z; 68 static_assert((X*)(Y1*)&z != (X*)(Y2*)&z, ""); 69} 70 71namespace ConstCast { 72 73constexpr int n1 = 0; 74constexpr int n2 = const_cast<int&>(n1); 75constexpr int *n3 = const_cast<int*>(&n1); 76constexpr int n4 = *const_cast<int*>(&n1); 77constexpr const int * const *n5 = const_cast<const int* const*>(&n3); 78constexpr int **n6 = const_cast<int**>(&n3); 79constexpr int n7 = **n5; 80constexpr int n8 = **n6; 81 82} 83 84namespace TemplateArgumentConversion { 85 template<int n> struct IntParam {}; 86 87 using IntParam0 = IntParam<0>; 88 using IntParam0 = IntParam<id(0)>; 89 using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}} 90} 91 92namespace CaseStatements { 93 void f(int n) { 94 switch (n) { 95 case MemberZero().zero: // expected-error {{did you mean to call it with no arguments?}} expected-note {{previous}} 96 case id(0): // expected-error {{duplicate case value '0'}} 97 return; 98 } 99 } 100} 101 102extern int &Recurse1; 103int &Recurse2 = Recurse1; // expected-note {{declared here}} 104int &Recurse1 = Recurse2; 105constexpr int &Recurse3 = Recurse2; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'Recurse2' is not a constant expression}} 106 107extern const int RecurseA; 108const int RecurseB = RecurseA; // expected-note {{declared here}} 109const int RecurseA = 10; 110constexpr int RecurseC = RecurseB; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'RecurseB' is not a constant expression}} 111 112namespace MemberEnum { 113 struct WithMemberEnum { 114 enum E { A = 42 }; 115 } wme; 116 117 static_assert(wme.A == 42, ""); 118} 119 120namespace DefaultArguments { 121 122const int z = int(); 123constexpr int Sum(int a = 0, const int &b = 0, const int *c = &z, char d = 0) { 124 return a + b + *c + d; 125} 126const int four = 4; 127constexpr int eight = 8; 128constexpr const int twentyseven = 27; 129static_assert(Sum() == 0, ""); 130static_assert(Sum(1) == 1, ""); 131static_assert(Sum(1, four) == 5, ""); 132static_assert(Sum(1, eight, &twentyseven) == 36, ""); 133static_assert(Sum(1, 2, &four, eight) == 15, ""); 134 135} 136 137namespace Ellipsis { 138 139// Note, values passed through an ellipsis can't actually be used. 140constexpr int F(int a, ...) { return a; } 141static_assert(F(0) == 0, ""); 142static_assert(F(1, 0) == 1, ""); 143static_assert(F(2, "test") == 2, ""); 144static_assert(F(3, &F) == 3, ""); 145int k = 0; // expected-note {{here}} 146static_assert(F(4, k) == 3, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'k'}} 147 148} 149 150namespace Recursion { 151 constexpr int fib(int n) { return n > 1 ? fib(n-1) + fib(n-2) : n; } 152 static_assert(fib(11) == 89, ""); 153 154 constexpr int gcd_inner(int a, int b) { 155 return b == 0 ? a : gcd_inner(b, a % b); 156 } 157 constexpr int gcd(int a, int b) { 158 return gcd_inner(max(a, b), min(a, b)); 159 } 160 161 static_assert(gcd(1749237, 5628959) == 7, ""); 162} 163 164namespace FunctionCast { 165 // When folding, we allow functions to be cast to different types. Such 166 // cast functions cannot be called, even if they're constexpr. 167 constexpr int f() { return 1; } 168 typedef double (*DoubleFn)(); 169 typedef int (*IntFn)(); 170 int a[(int)DoubleFn(f)()]; // expected-error {{variable length array}} expected-warning{{C99 feature}} 171 int b[(int)IntFn(f)()]; // ok 172} 173 174namespace StaticMemberFunction { 175 struct S { 176 static constexpr int k = 42; 177 static constexpr int f(int n) { return n * k + 2; } 178 } s; 179 180 constexpr int n = s.f(19); 181 static_assert(S::f(19) == 800, ""); 182 static_assert(s.f(19) == 800, ""); 183 static_assert(n == 800, ""); 184 185 constexpr int (*sf1)(int) = &S::f; 186 constexpr int (*sf2)(int) = &s.f; 187 constexpr const int *sk = &s.k; 188} 189 190namespace ParameterScopes { 191 192 const int k = 42; 193 constexpr const int &ObscureTheTruth(const int &a) { return a; } 194 constexpr const int &MaybeReturnJunk(bool b, const int a) { // expected-note 2{{declared here}} 195 return ObscureTheTruth(b ? a : k); 196 } 197 static_assert(MaybeReturnJunk(false, 0) == 42, ""); // ok 198 constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}} expected-note {{read of variable whose lifetime has ended}} 199 200 constexpr const int MaybeReturnNonstaticRef(bool b, const int a) { 201 return ObscureTheTruth(b ? a : k); 202 } 203 static_assert(MaybeReturnNonstaticRef(false, 0) == 42, ""); // ok 204 constexpr int b = MaybeReturnNonstaticRef(true, 0); // ok 205 206 constexpr int InternalReturnJunk(int n) { 207 return MaybeReturnJunk(true, n); // expected-note {{read of variable whose lifetime has ended}} 208 } 209 constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'InternalReturnJunk(0)'}} 210 211 constexpr int LToR(int &n) { return n; } 212 constexpr int GrabCallersArgument(bool which, int a, int b) { 213 return LToR(which ? b : a); 214 } 215 static_assert(GrabCallersArgument(false, 1, 2) == 1, ""); 216 static_assert(GrabCallersArgument(true, 4, 8) == 8, ""); 217 218} 219 220namespace Pointers { 221 222 constexpr int f(int n, const int *a, const int *b, const int *c) { 223 return n == 0 ? 0 : *a + f(n-1, b, c, a); 224 } 225 226 const int x = 1, y = 10, z = 100; 227 static_assert(f(23, &x, &y, &z) == 788, ""); 228 229 constexpr int g(int n, int a, int b, int c) { 230 return f(n, &a, &b, &c); 231 } 232 static_assert(g(23, x, y, z) == 788, ""); 233 234} 235 236namespace FunctionPointers { 237 238 constexpr int Double(int n) { return 2 * n; } 239 constexpr int Triple(int n) { return 3 * n; } 240 constexpr int Twice(int (*F)(int), int n) { return F(F(n)); } 241 constexpr int Quadruple(int n) { return Twice(Double, n); } 242 constexpr auto Select(int n) -> int (*)(int) { 243 return n == 2 ? &Double : n == 3 ? &Triple : n == 4 ? &Quadruple : 0; 244 } 245 constexpr int Apply(int (*F)(int), int n) { return F(n); } // expected-note {{subexpression}} 246 247 static_assert(1 + Apply(Select(4), 5) + Apply(Select(3), 7) == 42, ""); 248 249 constexpr int Invalid = Apply(Select(0), 0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'Apply(0, 0)'}} 250 251} 252 253namespace PointerComparison { 254 255int x, y; 256static_assert(&x == &y, "false"); // expected-error {{false}} 257static_assert(&x != &y, ""); 258constexpr bool g1 = &x == &y; 259constexpr bool g2 = &x != &y; 260constexpr bool g3 = &x <= &y; // expected-error {{must be initialized by a constant expression}} 261constexpr bool g4 = &x >= &y; // expected-error {{must be initialized by a constant expression}} 262constexpr bool g5 = &x < &y; // expected-error {{must be initialized by a constant expression}} 263constexpr bool g6 = &x > &y; // expected-error {{must be initialized by a constant expression}} 264 265struct S { int x, y; } s; 266static_assert(&s.x == &s.y, "false"); // expected-error {{false}} 267static_assert(&s.x != &s.y, ""); 268static_assert(&s.x <= &s.y, ""); 269static_assert(&s.x >= &s.y, "false"); // expected-error {{false}} 270static_assert(&s.x < &s.y, ""); 271static_assert(&s.x > &s.y, "false"); // expected-error {{false}} 272 273static_assert(0 == &y, "false"); // expected-error {{false}} 274static_assert(0 != &y, ""); 275constexpr bool n3 = 0 <= &y; // expected-error {{must be initialized by a constant expression}} 276constexpr bool n4 = 0 >= &y; // expected-error {{must be initialized by a constant expression}} 277constexpr bool n5 = 0 < &y; // expected-error {{must be initialized by a constant expression}} 278constexpr bool n6 = 0 > &y; // expected-error {{must be initialized by a constant expression}} 279 280static_assert(&x == 0, "false"); // expected-error {{false}} 281static_assert(&x != 0, ""); 282constexpr bool n9 = &x <= 0; // expected-error {{must be initialized by a constant expression}} 283constexpr bool n10 = &x >= 0; // expected-error {{must be initialized by a constant expression}} 284constexpr bool n11 = &x < 0; // expected-error {{must be initialized by a constant expression}} 285constexpr bool n12 = &x > 0; // expected-error {{must be initialized by a constant expression}} 286 287static_assert(&x == &x, ""); 288static_assert(&x != &x, "false"); // expected-error {{false}} 289static_assert(&x <= &x, ""); 290static_assert(&x >= &x, ""); 291static_assert(&x < &x, "false"); // expected-error {{false}} 292static_assert(&x > &x, "false"); // expected-error {{false}} 293 294constexpr S* sptr = &s; 295constexpr bool dyncast = sptr == dynamic_cast<S*>(sptr); // expected-error {{constant expression}} expected-note {{dynamic_cast}} 296 297struct U {}; 298struct Str { 299 int a : dynamic_cast<S*>(sptr) == dynamic_cast<S*>(sptr); // \ 300 expected-warning {{not an integral constant expression}} \ 301 expected-note {{dynamic_cast is not allowed in a constant expression}} 302 int b : reinterpret_cast<S*>(sptr) == reinterpret_cast<S*>(sptr); // \ 303 expected-warning {{not an integral constant expression}} \ 304 expected-note {{reinterpret_cast is not allowed in a constant expression}} 305 int c : (S*)(long)(sptr) == (S*)(long)(sptr); // \ 306 expected-warning {{not an integral constant expression}} \ 307 expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} 308 int d : (S*)(42) == (S*)(42); // \ 309 expected-warning {{not an integral constant expression}} \ 310 expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} 311 int e : (Str*)(sptr) == (Str*)(sptr); // \ 312 expected-warning {{not an integral constant expression}} \ 313 expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} 314 int f : &(U&)(*sptr) == &(U&)(*sptr); // \ 315 expected-warning {{not an integral constant expression}} \ 316 expected-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} 317 int g : (S*)(void*)(sptr) == sptr; // \ 318 expected-warning {{not an integral constant expression}} \ 319 expected-note {{cast from 'void *' is not allowed in a constant expression}} 320}; 321 322extern char externalvar[]; 323constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; // expected-error {{must be initialized by a constant expression}} 324constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} expected-warning {{unspecified}} 325static_assert(0 != "foo", ""); 326 327} 328 329namespace MaterializeTemporary { 330 331constexpr int f(const int &r) { return r; } 332constexpr int n = f(1); 333 334constexpr bool same(const int &a, const int &b) { return &a == &b; } 335constexpr bool sameTemporary(const int &n) { return same(n, n); } 336 337static_assert(n, ""); 338static_assert(!same(4, 4), ""); 339static_assert(same(n, n), ""); 340static_assert(sameTemporary(9), ""); 341 342struct A { int &&r; }; 343struct B { A &&a1; A &&a2; }; 344 345constexpr B b1 { { 1 }, { 2 } }; // expected-note {{temporary created here}} 346static_assert(&b1.a1 != &b1.a2, ""); 347static_assert(&b1.a1.r != &b1.a2.r, ""); // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}} 348 349constexpr B &&b2 { { 3 }, { 4 } }; // expected-note {{temporary created here}} 350static_assert(&b1 != &b2, ""); 351static_assert(&b1.a1 != &b2.a1, ""); // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}} 352 353constexpr thread_local B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} 354void foo() { 355 constexpr static B b1 { { 1 }, { 2 } }; // ok 356 constexpr thread_local B b2 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} 357 constexpr B b3 { { 1 }, { 2 } }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} 358} 359 360constexpr B &&b4 = ((1, 2), 3, 4, B { {10}, {{20}} }); // expected-warning 4{{unused}} 361static_assert(&b4 != &b2, ""); 362 363// Proposed DR: copy-elision doesn't trigger lifetime extension. 364constexpr B b5 = B{ {0}, {0} }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} 365 366namespace NestedNonStatic { 367 // Proposed DR: for a reference constant expression to refer to a static 368 // storage duration temporary, that temporary must itself be initialized 369 // by a constant expression (a core constant expression is not enough). 370 struct A { int &&r; }; 371 struct B { A &&a; }; 372 constexpr B a = { A{0} }; // ok 373 constexpr B b = { A(A{0}) }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}} 374} 375 376namespace FakeInitList { 377 struct init_list_3_ints { const int (&x)[3]; }; 378 struct init_list_2_init_list_3_ints { const init_list_3_ints (&x)[2]; }; 379 constexpr init_list_2_init_list_3_ints ils = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } }; 380} 381 382} 383 384constexpr int strcmp_ce(const char *p, const char *q) { 385 return (!*p || *p != *q) ? *p - *q : strcmp_ce(p+1, q+1); 386} 387 388namespace StringLiteral { 389 390template<typename Char> 391constexpr int MangleChars(const Char *p) { 392 return *p + 3 * (*p ? MangleChars(p+1) : 0); 393} 394 395static_assert(MangleChars("constexpr!") == 1768383, ""); 396static_assert(MangleChars(u8"constexpr!") == 1768383, ""); 397static_assert(MangleChars(L"constexpr!") == 1768383, ""); 398static_assert(MangleChars(u"constexpr!") == 1768383, ""); 399static_assert(MangleChars(U"constexpr!") == 1768383, ""); 400 401constexpr char c0 = "nought index"[0]; 402constexpr char c1 = "nice index"[10]; 403constexpr 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}} 404constexpr 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}} 405constexpr 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}} 406 407constexpr const char *p = "test" + 2; 408static_assert(*p == 's', ""); 409 410constexpr const char *max_iter(const char *a, const char *b) { 411 return *a < *b ? b : a; 412} 413constexpr const char *max_element(const char *a, const char *b) { 414 return (a+1 >= b) ? a : max_iter(a, max_element(a+1, b)); 415} 416 417constexpr char str[] = "the quick brown fox jumped over the lazy dog"; 418constexpr const char *max = max_element(begin(str), end(str)); 419static_assert(*max == 'z', ""); 420static_assert(max == str + 38, ""); 421 422static_assert(strcmp_ce("hello world", "hello world") == 0, ""); 423static_assert(strcmp_ce("hello world", "hello clang") > 0, ""); 424static_assert(strcmp_ce("constexpr", "test") < 0, ""); 425static_assert(strcmp_ce("", " ") < 0, ""); 426 427struct S { 428 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}} 429}; 430 431struct T { 432 char c[6]; 433 constexpr T() : c{"foo"} {} 434}; 435constexpr T t; 436 437static_assert(t.c[0] == 'f', ""); 438static_assert(t.c[1] == 'o', ""); 439static_assert(t.c[2] == 'o', ""); 440static_assert(t.c[3] == 0, ""); 441static_assert(t.c[4] == 0, ""); 442static_assert(t.c[5] == 0, ""); 443static_assert(t.c[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}} 444 445struct U { 446 wchar_t chars[6]; 447 int n; 448} constexpr u = { { L"test" }, 0 }; 449static_assert(u.chars[2] == L's', ""); 450 451struct V { 452 char c[4]; 453 constexpr V() : c("hi!") {} 454}; 455static_assert(V().c[1] == "i"[0], ""); 456 457namespace Parens { 458 constexpr unsigned char a[] = ("foo"), b[] = {"foo"}, c[] = {("foo")}, 459 d[4] = ("foo"), e[5] = {"foo"}, f[6] = {("foo")}; 460 static_assert(a[0] == 'f', ""); 461 static_assert(b[1] == 'o', ""); 462 static_assert(c[2] == 'o', ""); 463 static_assert(d[0] == 'f', ""); 464 static_assert(e[1] == 'o', ""); 465 static_assert(f[2] == 'o', ""); 466 static_assert(f[5] == 0, ""); 467 static_assert(f[6] == 0, ""); // expected-error {{constant expression}} expected-note {{one-past-the-end}} 468} 469 470} 471 472namespace Array { 473 474template<typename Iter> 475constexpr auto Sum(Iter begin, Iter end) -> decltype(+*begin) { 476 return begin == end ? 0 : *begin + Sum(begin+1, end); 477} 478 479constexpr int xs[] = { 1, 2, 3, 4, 5 }; 480constexpr int ys[] = { 5, 4, 3, 2, 1 }; 481constexpr int sum_xs = Sum(begin(xs), end(xs)); 482static_assert(sum_xs == 15, ""); 483 484constexpr int ZipFoldR(int (*F)(int x, int y, int c), int n, 485 const int *xs, const int *ys, int c) { 486 return n ? F( 487 *xs, // expected-note {{read of dereferenced one-past-the-end pointer}} 488 *ys, 489 ZipFoldR(F, n-1, xs+1, ys+1, c)) // \ 490 expected-note {{in call to 'ZipFoldR(&SubMul, 2, &xs[4], &ys[4], 1)'}} \ 491 expected-note {{in call to 'ZipFoldR(&SubMul, 1, &xs[5], &ys[5], 1)'}} 492 : c; 493} 494constexpr int MulAdd(int x, int y, int c) { return x * y + c; } 495constexpr int InnerProduct = ZipFoldR(MulAdd, 5, xs, ys, 0); 496static_assert(InnerProduct == 35, ""); 497 498constexpr int SubMul(int x, int y, int c) { return (x - y) * c; } 499constexpr int DiffProd = ZipFoldR(SubMul, 2, xs+3, ys+3, 1); 500static_assert(DiffProd == 8, ""); 501static_assert(ZipFoldR(SubMul, 3, xs+3, ys+3, 1), ""); // \ 502 expected-error {{constant expression}} \ 503 expected-note {{in call to 'ZipFoldR(&SubMul, 3, &xs[3], &ys[3], 1)'}} 504 505constexpr const int *p = xs + 3; 506constexpr int xs4 = p[1]; // ok 507constexpr int xs5 = p[2]; // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} 508constexpr int xs6 = p[3]; // expected-error {{constant expression}} expected-note {{cannot refer to element 6}} 509constexpr int xs0 = p[-3]; // ok 510constexpr int xs_1 = p[-4]; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} 511 512constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 513static_assert(zs[0][0][0][0] == 1, ""); 514static_assert(zs[1][1][1][1] == 16, ""); 515static_assert(zs[0][0][0][2] == 3, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} 516static_assert((&zs[0][0][0][2])[-1] == 2, ""); 517static_assert(**(**(zs + 1) + 1) == 11, ""); 518static_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}} 519static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2) == 11, ""); 520constexpr 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}} 521 522constexpr int fail(const int &p) { 523 return (&p)[64]; // expected-note {{cannot refer to element 64 of array of 2 elements}} 524} 525static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2)) == 11, ""); // \ 526expected-error {{static_assert expression is not an integral constant expression}} \ 527expected-note {{in call to 'fail(zs[1][0][1][0])'}} 528 529constexpr int arr[40] = { 1, 2, 3, [8] = 4 }; // expected-warning {{C99 feature}} 530constexpr int SumNonzero(const int *p) { 531 return *p + (*p ? SumNonzero(p+1) : 0); 532} 533constexpr int CountZero(const int *p, const int *q) { 534 return p == q ? 0 : (*p == 0) + CountZero(p+1, q); 535} 536static_assert(SumNonzero(arr) == 6, ""); 537static_assert(CountZero(arr, arr + 40) == 36, ""); 538 539struct ArrayElem { 540 constexpr ArrayElem() : n(0) {} 541 int n; 542 constexpr int f() const { return n; } 543}; 544struct ArrayRVal { 545 constexpr ArrayRVal() {} 546 ArrayElem elems[10]; 547}; 548static_assert(ArrayRVal().elems[3].f() == 0, ""); 549 550constexpr int selfref[2][2][2] = { 551 selfref[1][1][1] + 1, selfref[0][0][0] + 1, 552 selfref[1][0][1] + 1, selfref[0][1][0] + 1, 553 selfref[1][0][0] + 1, selfref[0][1][1] + 1 }; 554static_assert(selfref[0][0][0] == 1, ""); 555static_assert(selfref[0][0][1] == 2, ""); 556static_assert(selfref[0][1][0] == 1, ""); 557static_assert(selfref[0][1][1] == 2, ""); 558static_assert(selfref[1][0][0] == 1, ""); 559static_assert(selfref[1][0][1] == 3, ""); 560static_assert(selfref[1][1][0] == 0, ""); 561static_assert(selfref[1][1][1] == 0, ""); 562 563struct TrivialDefCtor { int n; }; 564typedef TrivialDefCtor TDCArray[2][2]; 565static_assert(TDCArray{}[1][1].n == 0, ""); 566 567struct NonAggregateTDC : TrivialDefCtor {}; 568typedef NonAggregateTDC NATDCArray[2][2]; 569static_assert(NATDCArray{}[1][1].n == 0, ""); 570 571} 572 573namespace DependentValues { 574 575struct I { int n; typedef I V[10]; }; 576I::V x, y; 577int g(); 578template<bool B, typename T> struct S : T { 579 int k; 580 void f() { 581 I::V &cells = B ? x : y; 582 I &i = cells[k]; 583 switch (i.n) {} 584 585 // FIXME: We should be able to diagnose this. 586 constexpr int n = g(); 587 588 constexpr int m = this->g(); // ok, could be constexpr 589 } 590}; 591 592} 593 594namespace Class { 595 596struct A { constexpr A(int a, int b) : k(a + b) {} int k; }; 597constexpr int fn(const A &a) { return a.k; } 598static_assert(fn(A(4,5)) == 9, ""); 599 600struct B { int n; int m; } constexpr b = { 0, b.n }; // expected-warning {{uninitialized}} 601struct C { 602 constexpr C(C *this_) : m(42), n(this_->m) {} // ok 603 int m, n; 604}; 605struct D { 606 C c; 607 constexpr D() : c(&c) {} 608}; 609static_assert(D().c.n == 42, ""); 610 611struct E { 612 constexpr E() : p(&p) {} 613 void *p; 614}; 615constexpr const E &e1 = E(); 616// This is a constant expression if we elide the copy constructor call, and 617// is not a constant expression if we don't! But we do, so it is. 618constexpr E e2 = E(); 619static_assert(e2.p == &e2.p, ""); 620constexpr E e3; 621static_assert(e3.p == &e3.p, ""); 622 623extern const class F f; 624struct F { 625 constexpr F() : p(&f.p) {} 626 const void *p; 627}; 628constexpr F f; 629 630struct G { 631 struct T { 632 constexpr T(T *p) : u1(), u2(p) {} 633 union U1 { 634 constexpr U1() {} 635 int a, b = 42; 636 } u1; 637 union U2 { 638 constexpr U2(T *p) : c(p->u1.b) {} 639 int c, d; 640 } u2; 641 } t; 642 constexpr G() : t(&t) {} 643} constexpr g; 644 645static_assert(g.t.u1.a == 42, ""); // expected-error {{constant expression}} expected-note {{read of member 'a' of union with active member 'b'}} 646static_assert(g.t.u1.b == 42, ""); 647static_assert(g.t.u2.c == 42, ""); 648static_assert(g.t.u2.d == 42, ""); // expected-error {{constant expression}} expected-note {{read of member 'd' of union with active member 'c'}} 649 650struct S { 651 int a, b; 652 const S *p; 653 double d; 654 const char *q; 655 656 constexpr S(int n, const S *p) : a(5), b(n), p(p), d(n), q("hello") {} 657}; 658 659S global(43, &global); 660 661static_assert(S(15, &global).b == 15, ""); 662 663constexpr bool CheckS(const S &s) { 664 return s.a == 5 && s.b == 27 && s.p == &global && s.d == 27. && s.q[3] == 'l'; 665} 666static_assert(CheckS(S(27, &global)), ""); 667 668struct Arr { 669 char arr[3]; 670 constexpr Arr() : arr{'x', 'y', 'z'} {} 671}; 672constexpr int hash(Arr &&a) { 673 return a.arr[0] + a.arr[1] * 0x100 + a.arr[2] * 0x10000; 674} 675constexpr int k = hash(Arr()); 676static_assert(k == 0x007a7978, ""); 677 678 679struct AggregateInit { 680 const char &c; 681 int n; 682 double d; 683 int arr[5]; 684 void *p; 685}; 686 687constexpr AggregateInit agg1 = { "hello"[0] }; 688 689static_assert(strcmp_ce(&agg1.c, "hello") == 0, ""); 690static_assert(agg1.n == 0, ""); 691static_assert(agg1.d == 0.0, ""); 692static_assert(agg1.arr[-1] == 0, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} 693static_assert(agg1.arr[0] == 0, ""); 694static_assert(agg1.arr[4] == 0, ""); 695static_assert(agg1.arr[5] == 0, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end}} 696static_assert(agg1.p == nullptr, ""); 697 698static constexpr const unsigned char uc[] = { "foo" }; 699static_assert(uc[0] == 'f', ""); 700static_assert(uc[3] == 0, ""); 701 702namespace SimpleDerivedClass { 703 704struct B { 705 constexpr B(int n) : a(n) {} 706 int a; 707}; 708struct D : B { 709 constexpr D(int n) : B(n) {} 710}; 711constexpr D d(3); 712static_assert(d.a == 3, ""); 713 714} 715 716struct Bottom { constexpr Bottom() {} }; 717struct Base : Bottom { 718 constexpr Base(int a = 42, const char *b = "test") : a(a), b(b) {} 719 int a; 720 const char *b; 721}; 722struct Base2 : Bottom { 723 constexpr Base2(const int &r) : r(r) {} 724 int q = 123; 725 const int &r; 726}; 727struct Derived : Base, Base2 { 728 constexpr Derived() : Base(76), Base2(a) {} 729 int c = r + b[1]; 730}; 731 732constexpr bool operator==(const Base &a, const Base &b) { 733 return a.a == b.a && strcmp_ce(a.b, b.b) == 0; 734} 735 736constexpr Base base; 737constexpr Base base2(76); 738constexpr Derived derived; 739static_assert(derived.a == 76, ""); 740static_assert(derived.b[2] == 's', ""); 741static_assert(derived.c == 76 + 'e', ""); 742static_assert(derived.q == 123, ""); 743static_assert(derived.r == 76, ""); 744static_assert(&derived.r == &derived.a, ""); 745 746static_assert(!(derived == base), ""); 747static_assert(derived == base2, ""); 748 749constexpr Bottom &bot1 = (Base&)derived; 750constexpr Bottom &bot2 = (Base2&)derived; 751static_assert(&bot1 != &bot2, ""); 752 753constexpr Bottom *pb1 = (Base*)&derived; 754constexpr Bottom *pb2 = (Base2*)&derived; 755static_assert(&pb1 != &pb2, ""); 756static_assert(pb1 == &bot1, ""); 757static_assert(pb2 == &bot2, ""); 758 759constexpr Base2 &fail = (Base2&)bot1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}} 760constexpr Base &fail2 = (Base&)*pb2; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base'}} 761constexpr Base2 &ok2 = (Base2&)bot2; 762static_assert(&ok2 == &derived, ""); 763 764constexpr Base2 *pfail = (Base2*)pb1; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base2'}} 765constexpr Base *pfail2 = (Base*)&bot2; // expected-error {{constant expression}} expected-note {{cannot cast object of dynamic type 'const Class::Derived' to type 'Class::Base'}} 766constexpr Base2 *pok2 = (Base2*)pb2; 767static_assert(pok2 == &derived, ""); 768static_assert(&ok2 == pok2, ""); 769static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, ""); 770static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, ""); 771 772// Core issue 903: we do not perform constant evaluation when checking for a 773// null pointer in C++11. Just check for an integer literal with value 0. 774constexpr Base *nullB = 42 - 6 * 7; // expected-error {{cannot initialize a variable of type 'Class::Base *const' with an rvalue of type 'int'}} 775constexpr Base *nullB1 = 0; 776static_assert((Bottom*)nullB == 0, ""); 777static_assert((Derived*)nullB == 0, ""); 778static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, ""); 779Base *nullB2 = '\0'; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'char'}} 780Base *nullB3 = (0); 781Base *nullB4 = false; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'bool'}} 782Base *nullB5 = ((0ULL)); 783Base *nullB6 = 0.; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'double'}} 784enum Null { kNull }; 785Base *nullB7 = kNull; // expected-error {{cannot initialize a variable of type 'Class::Base *' with an rvalue of type 'Class::Null'}} 786static_assert(nullB1 == (1 - 1), ""); // expected-error {{comparison between pointer and integer}} 787 788 789 790namespace ConversionOperators { 791 792struct T { 793 constexpr T(int n) : k(5*n - 3) {} 794 constexpr operator int() const { return k; } 795 int k; 796}; 797 798struct S { 799 constexpr S(int n) : k(2*n + 1) {} 800 constexpr operator int() const { return k; } 801 constexpr operator T() const { return T(k); } 802 int k; 803}; 804 805constexpr bool check(T a, T b) { return a == b.k; } 806 807static_assert(S(5) == 11, ""); 808static_assert(check(S(5), 11), ""); 809 810namespace PR14171 { 811 812struct X { 813 constexpr (operator int)() const { return 0; } 814}; 815static_assert(X() == 0, ""); 816 817} 818 819} 820 821} 822 823namespace Temporaries { 824 825struct S { 826 constexpr S() {} 827 constexpr int f() const; 828 constexpr int g() const; 829}; 830struct T : S { 831 constexpr T(int n) : S(), n(n) {} 832 int n; 833}; 834constexpr int S::f() const { 835 return static_cast<const T*>(this)->n; // expected-note {{cannot cast}} 836} 837constexpr int S::g() const { 838 // FIXME: Better diagnostic for this. 839 return this->*(int(S::*))&T::n; // expected-note {{subexpression}} 840} 841// The T temporary is implicitly cast to an S subobject, but we can recover the 842// T full-object via a base-to-derived cast, or a derived-to-base-casted member 843// pointer. 844static_assert(S().f(), ""); // expected-error {{constant expression}} expected-note {{in call to '&Temporaries::S()->f()'}} 845static_assert(S().g(), ""); // expected-error {{constant expression}} expected-note {{in call to '&Temporaries::S()->g()'}} 846static_assert(T(3).f() == 3, ""); 847static_assert(T(4).g() == 4, ""); 848 849constexpr int f(const S &s) { 850 return static_cast<const T&>(s).n; 851} 852constexpr int n = f(T(5)); 853static_assert(f(T(5)) == 5, ""); 854 855constexpr bool b(int n) { return &n; } 856static_assert(b(0), ""); 857 858} 859 860namespace Union { 861 862union U { 863 int a; 864 int b; 865}; 866 867constexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } }; // expected-warning 4{{C99 feature}} 868static_assert(u[0].a == 0, ""); 869static_assert(u[0].b, ""); // expected-error {{constant expression}} expected-note {{read of member 'b' of union with active member 'a'}} 870static_assert(u[1].b == 1, ""); 871static_assert((&u[1].b)[1] == 2, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}} 872static_assert(*(&(u[1].b) + 1 + 1) == 3, ""); // expected-error {{constant expression}} expected-note {{cannot refer to element 2 of non-array object}} 873static_assert((&(u[1]) + 1 + 1)->b == 3, ""); 874 875constexpr U v = {}; 876static_assert(v.a == 0, ""); 877 878union Empty {}; 879constexpr Empty e = {}; 880 881// Make sure we handle trivial copy constructors for unions. 882constexpr U x = {42}; 883constexpr U y = x; 884static_assert(y.a == 42, ""); 885static_assert(y.b == 42, ""); // expected-error {{constant expression}} expected-note {{'b' of union with active member 'a'}} 886 887} 888 889namespace MemberPointer { 890 struct A { 891 constexpr A(int n) : n(n) {} 892 int n; 893 constexpr int f() const { return n + 3; } 894 }; 895 constexpr A a(7); 896 static_assert(A(5).*&A::n == 5, ""); 897 static_assert((&a)->*&A::n == 7, ""); 898 static_assert((A(8).*&A::f)() == 11, ""); 899 static_assert(((&a)->*&A::f)() == 10, ""); 900 901 struct B : A { 902 constexpr B(int n, int m) : A(n), m(m) {} 903 int m; 904 constexpr int g() const { return n + m + 1; } 905 }; 906 constexpr B b(9, 13); 907 static_assert(B(4, 11).*&A::n == 4, ""); 908 static_assert(B(4, 11).*&B::m == 11, ""); 909 static_assert(B(4, 11).*(int(A::*))&B::m == 11, ""); 910 static_assert((&b)->*&A::n == 9, ""); 911 static_assert((&b)->*&B::m == 13, ""); 912 static_assert((&b)->*(int(A::*))&B::m == 13, ""); 913 static_assert((B(4, 11).*&A::f)() == 7, ""); 914 static_assert((B(4, 11).*&B::g)() == 16, ""); 915 static_assert((B(4, 11).*(int(A::*)()const)&B::g)() == 16, ""); 916 static_assert(((&b)->*&A::f)() == 12, ""); 917 static_assert(((&b)->*&B::g)() == 23, ""); 918 static_assert(((&b)->*(int(A::*)()const)&B::g)() == 23, ""); 919 920 struct S { 921 constexpr S(int m, int n, int (S::*pf)() const, int S::*pn) : 922 m(m), n(n), pf(pf), pn(pn) {} 923 constexpr S() : m(), n(), pf(&S::f), pn(&S::n) {} 924 925 constexpr int f() const { return this->*pn; } 926 virtual int g() const; 927 928 int m, n; 929 int (S::*pf)() const; 930 int S::*pn; 931 }; 932 933 constexpr int S::*pm = &S::m; 934 constexpr int S::*pn = &S::n; 935 constexpr int (S::*pf)() const = &S::f; 936 constexpr int (S::*pg)() const = &S::g; 937 938 constexpr S s(2, 5, &S::f, &S::m); 939 940 static_assert((s.*&S::f)() == 2, ""); 941 static_assert((s.*s.pf)() == 2, ""); 942 943 static_assert(pf == &S::f, ""); 944 static_assert(pf == s.*&S::pf, ""); 945 static_assert(pm == &S::m, ""); 946 static_assert(pm != pn, ""); 947 static_assert(s.pn != pn, ""); 948 static_assert(s.pn == pm, ""); 949 static_assert(pg != nullptr, ""); 950 static_assert(pf != nullptr, ""); 951 static_assert((int S::*)nullptr == nullptr, ""); 952 static_assert(pg == pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}} 953 static_assert(pf != pg, ""); // expected-error {{constant expression}} expected-note {{comparison of pointer to virtual member function 'g' has unspecified value}} 954 955 template<int n> struct T : T<n-1> {}; 956 template<> struct T<0> { int n; }; 957 template<> struct T<30> : T<29> { int m; }; 958 959 T<17> t17; 960 T<30> t30; 961 962 constexpr int (T<10>::*deepn) = &T<0>::n; 963 static_assert(&(t17.*deepn) == &t17.n, ""); 964 static_assert(deepn == &T<2>::n, ""); 965 966 constexpr int (T<15>::*deepm) = (int(T<10>::*))&T<30>::m; 967 constexpr int *pbad = &(t17.*deepm); // expected-error {{constant expression}} 968 static_assert(&(t30.*deepm) == &t30.m, ""); 969 static_assert(deepm == &T<50>::m, ""); 970 static_assert(deepm != deepn, ""); 971 972 constexpr T<5> *p17_5 = &t17; 973 constexpr T<13> *p17_13 = (T<13>*)p17_5; 974 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>'}} 975 static_assert(&(p17_5->*(int(T<3>::*))deepn) == &t17.n, ""); 976 static_assert(&(p17_13->*deepn) == &t17.n, ""); 977 constexpr int *pbad2 = &(p17_13->*(int(T<9>::*))deepm); // expected-error {{constant expression}} 978 979 constexpr T<5> *p30_5 = &t30; 980 constexpr T<23> *p30_23 = (T<23>*)p30_5; 981 constexpr T<13> *p30_13 = p30_23; 982 static_assert(&(p30_5->*(int(T<3>::*))deepn) == &t30.n, ""); 983 static_assert(&(p30_13->*deepn) == &t30.n, ""); 984 static_assert(&(p30_23->*deepn) == &t30.n, ""); 985 static_assert(&(p30_5->*(int(T<2>::*))deepm) == &t30.m, ""); 986 static_assert(&(((T<17>*)p30_13)->*deepm) == &t30.m, ""); 987 static_assert(&(p30_23->*deepm) == &t30.m, ""); 988 989 struct Base { int n; }; 990 template<int N> struct Mid : Base {}; 991 struct Derived : Mid<0>, Mid<1> {}; 992 static_assert(&Mid<0>::n == &Mid<1>::n, ""); 993 static_assert((int Derived::*)(int Mid<0>::*)&Mid<0>::n != 994 (int Derived::*)(int Mid<1>::*)&Mid<1>::n, ""); 995 static_assert(&Mid<0>::n == (int Mid<0>::*)&Base::n, ""); 996} 997 998namespace ArrayBaseDerived { 999 1000 struct Base { 1001 constexpr Base() {} 1002 int n = 0; 1003 }; 1004 struct Derived : Base { 1005 constexpr Derived() {} 1006 constexpr const int *f() const { return &n; } 1007 }; 1008 1009 constexpr Derived a[10]; 1010 constexpr Derived *pd3 = const_cast<Derived*>(&a[3]); 1011 constexpr Base *pb3 = const_cast<Derived*>(&a[3]); 1012 static_assert(pb3 == pd3, ""); 1013 1014 // pb3 does not point to an array element. 1015 constexpr Base *pb4 = pb3 + 1; // ok, one-past-the-end pointer. 1016 constexpr int pb4n = pb4->n; // expected-error {{constant expression}} expected-note {{cannot access field of pointer past the end}} 1017 constexpr Base *err_pb5 = pb3 + 2; // expected-error {{constant expression}} expected-note {{cannot refer to element 2}} expected-note {{here}} 1018 constexpr int err_pb5n = err_pb5->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb5' is not a constant expression}} 1019 constexpr Base *err_pb2 = pb3 - 1; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}} expected-note {{here}} 1020 constexpr int err_pb2n = err_pb2->n; // expected-error {{constant expression}} expected-note {{initializer of 'err_pb2'}} 1021 constexpr Base *pb3a = pb4 - 1; 1022 1023 // pb4 does not point to a Derived. 1024 constexpr Derived *err_pd4 = (Derived*)pb4; // expected-error {{constant expression}} expected-note {{cannot access derived class of pointer past the end}} 1025 constexpr Derived *pd3a = (Derived*)pb3a; 1026 constexpr int pd3n = pd3a->n; 1027 1028 // pd3a still points to the Derived array. 1029 constexpr Derived *pd6 = pd3a + 3; 1030 static_assert(pd6 == &a[6], ""); 1031 constexpr Derived *pd9 = pd6 + 3; 1032 constexpr Derived *pd10 = pd6 + 4; 1033 constexpr int pd9n = pd9->n; // ok 1034 constexpr int err_pd10n = pd10->n; // expected-error {{constant expression}} expected-note {{cannot access base class of pointer past the end}} 1035 constexpr int pd0n = pd10[-10].n; 1036 constexpr int err_pdminus1n = pd10[-11].n; // expected-error {{constant expression}} expected-note {{cannot refer to element -1 of}} 1037 1038 constexpr Base *pb9 = pd9; 1039 constexpr const int *(Base::*pfb)() const = 1040 static_cast<const int *(Base::*)() const>(&Derived::f); 1041 static_assert((pb9->*pfb)() == &a[9].n, ""); 1042} 1043 1044namespace Complex { 1045 1046class complex { 1047 int re, im; 1048public: 1049 constexpr complex(int re = 0, int im = 0) : re(re), im(im) {} 1050 constexpr complex(const complex &o) : re(o.re), im(o.im) {} 1051 constexpr complex operator-() const { return complex(-re, -im); } 1052 friend constexpr complex operator+(const complex &l, const complex &r) { 1053 return complex(l.re + r.re, l.im + r.im); 1054 } 1055 friend constexpr complex operator-(const complex &l, const complex &r) { 1056 return l + -r; 1057 } 1058 friend constexpr complex operator*(const complex &l, const complex &r) { 1059 return complex(l.re * r.re - l.im * r.im, l.re * r.im + l.im * r.re); 1060 } 1061 friend constexpr bool operator==(const complex &l, const complex &r) { 1062 return l.re == r.re && l.im == r.im; 1063 } 1064 constexpr bool operator!=(const complex &r) const { 1065 return re != r.re || im != r.im; 1066 } 1067 constexpr int real() const { return re; } 1068 constexpr int imag() const { return im; } 1069}; 1070 1071constexpr complex i = complex(0, 1); 1072constexpr complex k = (3 + 4*i) * (6 - 4*i); 1073static_assert(complex(1,0).real() == 1, ""); 1074static_assert(complex(1,0).imag() == 0, ""); 1075static_assert(((complex)1).imag() == 0, ""); 1076static_assert(k.real() == 34, ""); 1077static_assert(k.imag() == 12, ""); 1078static_assert(k - 34 == 12*i, ""); 1079static_assert((complex)1 == complex(1), ""); 1080static_assert((complex)1 != complex(0, 1), ""); 1081static_assert(complex(1) == complex(1), ""); 1082static_assert(complex(1) != complex(0, 1), ""); 1083constexpr complex makeComplex(int re, int im) { return complex(re, im); } 1084static_assert(makeComplex(1,0) == complex(1), ""); 1085static_assert(makeComplex(1,0) != complex(0, 1), ""); 1086 1087class complex_wrap : public complex { 1088public: 1089 constexpr complex_wrap(int re, int im = 0) : complex(re, im) {} 1090 constexpr complex_wrap(const complex_wrap &o) : complex(o) {} 1091}; 1092 1093static_assert((complex_wrap)1 == complex(1), ""); 1094static_assert((complex)1 != complex_wrap(0, 1), ""); 1095static_assert(complex(1) == complex_wrap(1), ""); 1096static_assert(complex_wrap(1) != complex(0, 1), ""); 1097constexpr complex_wrap makeComplexWrap(int re, int im) { 1098 return complex_wrap(re, im); 1099} 1100static_assert(makeComplexWrap(1,0) == complex(1), ""); 1101static_assert(makeComplexWrap(1,0) != complex(0, 1), ""); 1102 1103} 1104 1105namespace PR11595 { 1106 struct A { constexpr bool operator==(int x) const { return true; } }; 1107 struct B { B(); A& x; }; 1108 static_assert(B().x == 3, ""); // expected-error {{constant expression}} expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}} 1109 1110 constexpr bool f(int k) { // expected-error {{constexpr function never produces a constant expression}} 1111 return B().x == k; // expected-note {{non-literal type 'PR11595::B' cannot be used in a constant expression}} 1112 } 1113} 1114 1115namespace ExprWithCleanups { 1116 struct A { A(); ~A(); int get(); }; 1117 constexpr int get(bool FromA) { return FromA ? A().get() : 1; } 1118 constexpr int n = get(false); 1119} 1120 1121namespace Volatile { 1122 1123volatile constexpr int n1 = 0; // expected-note {{here}} 1124volatile const int n2 = 0; // expected-note {{here}} 1125int n3 = 37; // expected-note {{declared here}} 1126 1127constexpr int m1 = n1; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}} 1128constexpr int m2 = n2; // expected-error {{constant expression}} expected-note {{read of volatile-qualified type 'const volatile int'}} 1129constexpr int m1b = const_cast<const int&>(n1); // expected-error {{constant expression}} expected-note {{read of volatile object 'n1'}} 1130constexpr int m2b = const_cast<const int&>(n2); // expected-error {{constant expression}} expected-note {{read of volatile object 'n2'}} 1131 1132struct T { int n; }; 1133const T t = { 42 }; // expected-note {{declared here}} 1134 1135constexpr int f(volatile int &&r) { 1136 return r; // expected-note {{read of volatile-qualified type 'volatile int'}} 1137} 1138constexpr int g(volatile int &&r) { 1139 return const_cast<int&>(r); // expected-note {{read of volatile temporary is not allowed in a constant expression}} 1140} 1141struct S { 1142 int j : f(0); // expected-error {{constant expression}} expected-note {{in call to 'f(0)'}} 1143 int k : g(0); // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'g(0)'}} 1144 int l : n3; // expected-error {{constant expression}} expected-note {{read of non-const variable}} 1145 int m : t.n; // expected-error {{constant expression}} expected-note {{read of non-constexpr variable}} 1146}; 1147 1148} 1149 1150namespace ExternConstexpr { 1151 extern constexpr int n = 0; 1152 extern constexpr int m; // expected-error {{constexpr variable declaration must be a definition}} 1153 void f() { 1154 extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}} 1155 constexpr int j = 0; 1156 constexpr int k; // expected-error {{default initialization of an object of const type}} 1157 } 1158} 1159 1160namespace ComplexConstexpr { 1161 constexpr _Complex float test1 = {}; 1162 constexpr _Complex float test2 = {1}; 1163 constexpr _Complex double test3 = {1,2}; 1164 constexpr _Complex int test4 = {4}; 1165 constexpr _Complex int test5 = 4; 1166 constexpr _Complex int test6 = {5,6}; 1167 typedef _Complex float fcomplex; 1168 constexpr fcomplex test7 = fcomplex(); 1169 1170 constexpr const double &t2r = __real test3; 1171 constexpr const double &t2i = __imag test3; 1172 static_assert(&t2r + 1 == &t2i, ""); 1173 static_assert(t2r == 1.0, ""); 1174 static_assert(t2i == 2.0, ""); 1175 constexpr const double *t2p = &t2r; 1176 static_assert(t2p[-1] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element -1 of array of 2 elements}} 1177 static_assert(t2p[0] == 1.0, ""); 1178 static_assert(t2p[1] == 2.0, ""); 1179 static_assert(t2p[2] == 0.0, ""); // expected-error {{constant expr}} expected-note {{one-past-the-end pointer}} 1180 static_assert(t2p[3] == 0.0, ""); // expected-error {{constant expr}} expected-note {{cannot refer to element 3 of array of 2 elements}} 1181 constexpr _Complex float *p = 0; 1182 constexpr float pr = __real *p; // expected-error {{constant expr}} expected-note {{cannot access real component of null}} 1183 constexpr float pi = __imag *p; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of null}} 1184 constexpr const _Complex double *q = &test3 + 1; 1185 constexpr double qr = __real *q; // expected-error {{constant expr}} expected-note {{cannot access real component of pointer past the end}} 1186 constexpr double qi = __imag *q; // expected-error {{constant expr}} expected-note {{cannot access imaginary component of pointer past the end}} 1187 1188 static_assert(__real test6 == 5, ""); 1189 static_assert(__imag test6 == 6, ""); 1190 static_assert(&__imag test6 == &__real test6 + 1, ""); 1191} 1192 1193// _Atomic(T) is exactly like T for the purposes of constant expression 1194// evaluation.. 1195namespace Atomic { 1196 constexpr _Atomic int n = 3; 1197 1198 struct S { _Atomic(double) d; }; 1199 constexpr S s = { 0.5 }; 1200 constexpr double d1 = s.d; 1201 constexpr double d2 = n; 1202 constexpr _Atomic double d3 = n; 1203 1204 constexpr _Atomic(int) n2 = d3; 1205 static_assert(d1 == 0.5, ""); 1206 static_assert(d3 == 3.0, ""); 1207 1208 namespace PR16056 { 1209 struct TestVar { 1210 _Atomic(int) value; 1211 constexpr TestVar(int value) : value(value) {} 1212 }; 1213 constexpr TestVar testVar{-1}; 1214 static_assert(testVar.value == -1, ""); 1215 } 1216} 1217 1218namespace InstantiateCaseStmt { 1219 template<int x> constexpr int f() { return x; } 1220 template<int x> int g(int c) { switch(c) { case f<x>(): return 1; } return 0; } 1221 int gg(int c) { return g<4>(c); } 1222} 1223 1224namespace ConvertedConstantExpr { 1225 extern int &m; 1226 extern int &n; 1227 1228 constexpr int k = 4; 1229 int &m = const_cast<int&>(k); 1230 1231 // If we have nothing more interesting to say, ensure we don't produce a 1232 // useless note and instead just point to the non-constant subexpression. 1233 enum class E { 1234 em = m, 1235 en = n, // expected-error {{not a constant expression}} 1236 eo = (m + 1237 n // expected-error {{not a constant expression}} 1238 ), 1239 eq = reinterpret_cast<int>((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}} 1240 }; 1241} 1242 1243namespace IndirectField { 1244 struct S { 1245 struct { // expected-warning {{GNU extension}} 1246 union { // expected-warning {{declared in an anonymous struct}} 1247 struct { // expected-warning {{GNU extension}} expected-warning {{declared in an anonymous union}} 1248 int a; 1249 int b; 1250 }; 1251 int c; 1252 }; 1253 int d; 1254 }; 1255 union { 1256 int e; 1257 int f; 1258 }; 1259 constexpr S(int a, int b, int d, int e) : a(a), b(b), d(d), e(e) {} 1260 constexpr S(int c, int d, int f) : c(c), d(d), f(f) {} 1261 }; 1262 1263 constexpr S s1(1, 2, 3, 4); 1264 constexpr S s2(5, 6, 7); 1265 1266 // FIXME: The diagnostics here do a very poor job of explaining which unnamed 1267 // member is active and which is requested. 1268 static_assert(s1.a == 1, ""); 1269 static_assert(s1.b == 2, ""); 1270 static_assert(s1.c == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} 1271 static_assert(s1.d == 3, ""); 1272 static_assert(s1.e == 4, ""); 1273 static_assert(s1.f == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} 1274 1275 static_assert(s2.a == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} 1276 static_assert(s2.b == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} 1277 static_assert(s2.c == 5, ""); 1278 static_assert(s2.d == 6, ""); 1279 static_assert(s2.e == 0, ""); // expected-error {{constant expression}} expected-note {{union with active member}} 1280 static_assert(s2.f == 7, ""); 1281} 1282 1283// DR1405: don't allow reading mutable members in constant expressions. 1284namespace MutableMembers { 1285 struct MM { 1286 mutable int n; // expected-note 3{{declared here}} 1287 } constexpr mm = { 4 }; 1288 constexpr int mmn = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}} 1289 int x = (mm.n = 1, 3); 1290 constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}} 1291 1292 // Here's one reason why allowing this would be a disaster... 1293 template<int n> struct Id { int k = n; }; 1294 int f() { 1295 constexpr MM m = { 0 }; 1296 ++m.n; 1297 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}} 1298 } 1299 1300 struct A { int n; }; 1301 struct B { mutable A a; }; // expected-note {{here}} 1302 struct C { B b; }; 1303 constexpr C c[3] = {}; 1304 constexpr int k = c[1].b.a.n; // expected-error {{constant expression}} expected-note {{mutable}} 1305} 1306 1307namespace Fold { 1308 1309 // This macro forces its argument to be constant-folded, even if it's not 1310 // otherwise a constant expression. 1311 #define fold(x) (__builtin_constant_p(x) ? (x) : (x)) 1312 1313 constexpr int n = (int)(char*)123; // expected-error {{constant expression}} expected-note {{reinterpret_cast}} 1314 constexpr int m = fold((int)(char*)123); // ok 1315 static_assert(m == 123, ""); 1316 1317 #undef fold 1318 1319} 1320 1321namespace DR1454 { 1322 1323constexpr const int &f(const int &n) { return n; } 1324constexpr int k1 = f(0); // ok 1325 1326struct Wrap { 1327 const int &value; 1328}; 1329constexpr const Wrap &g(const Wrap &w) { return w; } 1330constexpr int k2 = g({0}).value; // ok 1331 1332// The temporary here has static storage duration, so we can bind a constexpr 1333// reference to it. 1334constexpr const int &i = 1; 1335constexpr const int j = i; 1336static_assert(j == 1, ""); 1337 1338// The temporary here is not const, so it can't be read outside the expression 1339// in which it was created (per the C++14 rules, which we use to avoid a C++11 1340// defect). 1341constexpr int &&k = 1; // expected-note {{temporary created here}} 1342constexpr const int l = k; // expected-error {{constant expression}} expected-note {{read of temporary}} 1343 1344void f() { 1345 // The temporary here has automatic storage duration, so we can't bind a 1346 // constexpr reference to it. 1347 constexpr const int &i = 1; // expected-error {{constant expression}} expected-note 2{{temporary}} 1348} 1349 1350} 1351 1352namespace RecursiveOpaqueExpr { 1353 template<typename Iter> 1354 constexpr auto LastNonzero(Iter p, Iter q) -> decltype(+*p) { 1355 return p != q ? (LastNonzero(p+1, q) ?: *p) : 0; // expected-warning {{GNU}} 1356 } 1357 1358 constexpr int arr1[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 0 }; 1359 static_assert(LastNonzero(begin(arr1), end(arr1)) == 4, ""); 1360 1361 constexpr int arr2[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 5 }; 1362 static_assert(LastNonzero(begin(arr2), end(arr2)) == 5, ""); 1363 1364 constexpr int arr3[] = { 1365 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, 1366 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, 1367 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, 1368 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, 1369 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, 1370 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, 1371 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, 1372 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 }; 1373 static_assert(LastNonzero(begin(arr3), end(arr3)) == 2, ""); 1374} 1375 1376namespace VLASizeof { 1377 1378 void f(int k) { 1379 int arr[k]; // expected-warning {{C99}} 1380 constexpr int n = 1 + 1381 sizeof(arr) // expected-error {{constant expression}} 1382 * 3; 1383 } 1384} 1385 1386namespace CompoundLiteral { 1387 // FIXME: 1388 // We don't model the semantics of this correctly: the compound literal is 1389 // represented as a prvalue in the AST, but actually behaves like an lvalue. 1390 // We treat the compound literal as a temporary and refuse to produce a 1391 // pointer to it. This is OK: we're not required to treat this as a constant 1392 // in C++, and in C we model compound literals as lvalues. 1393 constexpr int *p = (int*)(int[1]){0}; // expected-warning {{C99}} expected-error {{constant expression}} expected-note 2{{temporary}} 1394} 1395 1396namespace Vector { 1397 typedef int __attribute__((vector_size(16))) VI4; 1398 constexpr VI4 f(int n) { 1399 return VI4 { n * 3, n + 4, n - 5, n / 6 }; 1400 } 1401 constexpr auto v1 = f(10); 1402 1403 typedef double __attribute__((vector_size(32))) VD4; 1404 constexpr VD4 g(int n) { 1405 return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 }; // expected-warning {{C99}} 1406 } 1407 constexpr auto v2 = g(4); 1408} 1409 1410// PR12626, redux 1411namespace InvalidClasses { 1412 void test0() { 1413 struct X; // expected-note {{forward declaration}} 1414 struct Y { bool b; X x; }; // expected-error {{field has incomplete type}} 1415 Y y; 1416 auto& b = y.b; 1417 } 1418} 1419 1420namespace NamespaceAlias { 1421 constexpr int f() { 1422 namespace NS = NamespaceAlias; // expected-warning {{use of this statement in a constexpr function is a C++1y extension}} 1423 return &NS::f != nullptr; 1424 } 1425} 1426 1427// Constructors can be implicitly constexpr, even for a non-literal type. 1428namespace ImplicitConstexpr { 1429 struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}} 1430 struct R { constexpr R() noexcept; constexpr R(const R&) noexcept; constexpr R(R&&) noexcept; ~R() noexcept; }; 1431 struct S { R r; }; // expected-note 3{{here}} 1432 struct T { T(const T&) noexcept; T(T &&) noexcept; ~T() noexcept; }; 1433 struct U { T t; }; // expected-note 3{{here}} 1434 static_assert(!__is_literal_type(Q), ""); 1435 static_assert(!__is_literal_type(R), ""); 1436 static_assert(!__is_literal_type(S), ""); 1437 static_assert(!__is_literal_type(T), ""); 1438 static_assert(!__is_literal_type(U), ""); 1439 struct Test { 1440 friend Q::Q() noexcept; // expected-error {{follows constexpr}} 1441 friend Q::Q(Q&&) noexcept; // expected-error {{follows constexpr}} 1442 friend Q::Q(const Q&) noexcept; // expected-error {{follows constexpr}} 1443 friend S::S() noexcept; // expected-error {{follows constexpr}} 1444 friend S::S(S&&) noexcept; // expected-error {{follows constexpr}} 1445 friend S::S(const S&) noexcept; // expected-error {{follows constexpr}} 1446 friend constexpr U::U() noexcept; // expected-error {{follows non-constexpr}} 1447 friend constexpr U::U(U&&) noexcept; // expected-error {{follows non-constexpr}} 1448 friend constexpr U::U(const U&) noexcept; // expected-error {{follows non-constexpr}} 1449 }; 1450} 1451 1452// Indirectly test that an implicit lvalue to xvalue conversion performed for 1453// an NRVO move operation isn't implemented as CK_LValueToRValue. 1454namespace PR12826 { 1455 struct Foo {}; 1456 constexpr Foo id(Foo x) { return x; } 1457 constexpr Foo res(id(Foo())); 1458} 1459 1460namespace PR13273 { 1461 struct U { 1462 int t; 1463 U() = default; 1464 }; 1465 1466 struct S : U { 1467 S() = default; 1468 }; 1469 1470 // S's default constructor isn't constexpr, because U's default constructor 1471 // doesn't initialize 't', but it's trivial, so value-initialization doesn't 1472 // actually call it. 1473 static_assert(S{}.t == 0, ""); 1474} 1475 1476namespace PR12670 { 1477 struct S { 1478 constexpr S(int a0) : m(a0) {} 1479 constexpr S() : m(6) {} 1480 int m; 1481 }; 1482 constexpr S x[3] = { {4}, 5 }; 1483 static_assert(x[0].m == 4, ""); 1484 static_assert(x[1].m == 5, ""); 1485 static_assert(x[2].m == 6, ""); 1486} 1487 1488// Indirectly test that an implicit lvalue-to-rvalue conversion is performed 1489// when a conditional operator has one argument of type void and where the other 1490// is a glvalue of class type. 1491namespace ConditionalLValToRVal { 1492 struct A { 1493 constexpr A(int a) : v(a) {} 1494 int v; 1495 }; 1496 1497 constexpr A f(const A &a) { 1498 return a.v == 0 ? throw a : a; 1499 } 1500 1501 constexpr A a(4); 1502 static_assert(f(a).v == 4, ""); 1503} 1504 1505namespace TLS { 1506 __thread int n; 1507 int m; 1508 1509 constexpr bool b = &n == &n; 1510 1511 constexpr int *p = &n; // expected-error{{constexpr variable 'p' must be initialized by a constant expression}} 1512 1513 constexpr int *f() { return &n; } 1514 constexpr int *q = f(); // expected-error{{constexpr variable 'q' must be initialized by a constant expression}} 1515 constexpr bool c = f() == f(); 1516 1517 constexpr int *g() { return &m; } 1518 constexpr int *r = g(); 1519} 1520 1521namespace Void { 1522 constexpr void f() { return; } // expected-error{{constexpr function's return type 'void' is not a literal type}} 1523 1524 void assert_failed(const char *msg, const char *file, int line); // expected-note {{declared here}} 1525#define ASSERT(expr) ((expr) ? static_cast<void>(0) : assert_failed(#expr, __FILE__, __LINE__)) 1526 template<typename T, size_t S> 1527 constexpr T get(T (&a)[S], size_t k) { 1528 return ASSERT(k > 0 && k < S), a[k]; // expected-note{{non-constexpr function 'assert_failed'}} 1529 } 1530#undef ASSERT 1531 template int get(int (&a)[4], size_t); 1532 constexpr int arr[] = { 4, 1, 2, 3, 4 }; 1533 static_assert(get(arr, 1) == 1, ""); 1534 static_assert(get(arr, 4) == 4, ""); 1535 static_assert(get(arr, 0) == 4, ""); // expected-error{{not an integral constant expression}} \ 1536 // expected-note{{in call to 'get(arr, 0)'}} 1537} 1538 1539namespace std { struct type_info; } 1540 1541namespace TypeId { 1542 struct A { virtual ~A(); }; 1543 A f(); 1544 A &g(); 1545 constexpr auto &x = typeid(f()); 1546 constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \ 1547 // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}} 1548} 1549 1550namespace PR14203 { 1551 struct duration { 1552 constexpr duration() {} 1553 constexpr operator int() const { return 0; } 1554 }; 1555 template<typename T> void f() { 1556 // If we want to evaluate this at the point of the template definition, we 1557 // need to trigger the implicit definition of the move constructor at that 1558 // point. 1559 // FIXME: C++ does not permit us to implicitly define it at the appropriate 1560 // times, since it is only allowed to be implicitly defined when it is 1561 // odr-used. 1562 constexpr duration d = duration(); 1563 } 1564 // FIXME: It's unclear whether this is valid. On the one hand, we're not 1565 // allowed to generate a move constructor. On the other hand, if we did, 1566 // this would be a constant expression. For now, we generate a move 1567 // constructor here. 1568 int n = sizeof(short{duration(duration())}); 1569} 1570 1571namespace ArrayEltInit { 1572 struct A { 1573 constexpr A() : p(&p) {} 1574 void *p; 1575 }; 1576 constexpr A a[10]; 1577 static_assert(a[0].p == &a[0].p, ""); 1578 static_assert(a[9].p == &a[9].p, ""); 1579 static_assert(a[0].p != &a[9].p, ""); 1580 static_assert(a[9].p != &a[0].p, ""); 1581 1582 constexpr A b[10] = {}; 1583 static_assert(b[0].p == &b[0].p, ""); 1584 static_assert(b[9].p == &b[9].p, ""); 1585 static_assert(b[0].p != &b[9].p, ""); 1586 static_assert(b[9].p != &b[0].p, ""); 1587} 1588 1589namespace PR15884 { 1590 struct S {}; 1591 constexpr S f() { return {}; } 1592 constexpr S *p = &f(); 1593 // expected-error@-1 {{taking the address of a temporary}} 1594 // expected-error@-2 {{constexpr variable 'p' must be initialized by a constant expression}} 1595 // expected-note@-3 {{pointer to temporary is not a constant expression}} 1596 // expected-note@-4 {{temporary created here}} 1597} 1598 1599namespace AfterError { 1600 // FIXME: Suppress the 'no return statements' diagnostic if the body is invalid. 1601 constexpr int error() { // expected-error {{no return statement}} 1602 return foobar; // expected-error {{undeclared identifier}} 1603 } 1604 constexpr int k = error(); // expected-error {{must be initialized by a constant expression}} 1605} 1606 1607namespace std { 1608 typedef decltype(sizeof(int)) size_t; 1609 1610 template <class _E> 1611 class initializer_list 1612 { 1613 const _E* __begin_; 1614 size_t __size_; 1615 1616 constexpr initializer_list(const _E* __b, size_t __s) 1617 : __begin_(__b), 1618 __size_(__s) 1619 {} 1620 1621 public: 1622 typedef _E value_type; 1623 typedef const _E& reference; 1624 typedef const _E& const_reference; 1625 typedef size_t size_type; 1626 1627 typedef const _E* iterator; 1628 typedef const _E* const_iterator; 1629 1630 constexpr initializer_list() : __begin_(nullptr), __size_(0) {} 1631 1632 constexpr size_t size() const {return __size_;} 1633 constexpr const _E* begin() const {return __begin_;} 1634 constexpr const _E* end() const {return __begin_ + __size_;} 1635 }; 1636} 1637 1638namespace InitializerList { 1639 constexpr int sum(const int *b, const int *e) { 1640 return b != e ? *b + sum(b+1, e) : 0; 1641 } 1642 constexpr int sum(std::initializer_list<int> ints) { 1643 return sum(ints.begin(), ints.end()); 1644 } 1645 static_assert(sum({1, 2, 3, 4, 5}) == 15, ""); 1646} 1647