1 // RUN: %clang_cc1 -std=c++1y -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu 2 3 struct S { 4 // dummy ctor to make this a literal type 5 constexpr S(int); 6 7 S(); 8 9 int arr[10]; 10 11 constexpr int &get(int n) { return arr[n]; } 12 constexpr const int &get(int n) const { return arr[n]; } 13 }; 14 15 S s = S(); 16 const S &sr = s; 17 static_assert(&s.get(4) - &sr.get(2) == 2, ""); 18 19 // Compound-statements can be used in constexpr functions. 20 constexpr int e() {{{{}} return 5; }} 21 static_assert(e() == 5, ""); 22 23 // Types can be defined in constexpr functions. 24 constexpr int f() { 25 enum E { e1, e2, e3 }; 26 27 struct S { 28 constexpr S(E e) : e(e) {} 29 constexpr int get() { return e; } 30 E e; 31 }; 32 33 return S(e2).get(); 34 } 35 static_assert(f() == 1, ""); 36 37 // Variables can be declared in constexpr functions. 38 constexpr int g(int k) { 39 const int n = 9; 40 int k2 = k * k; 41 int k3 = k2 * k; 42 return 3 * k3 + 5 * k2 + n * k - 20; 43 } 44 static_assert(g(2) == 42, ""); 45 constexpr int h(int n) { 46 static const int m = n; // expected-error {{static variable not permitted in a constexpr function}} 47 return m; 48 } 49 constexpr int i(int n) { 50 thread_local const int m = n; // expected-error {{thread_local variable not permitted in a constexpr function}} 51 return m; 52 } 53 54 // if-statements can be used in constexpr functions. 55 constexpr int j(int k) { 56 if (k == 5) 57 return 1; 58 if (k == 1) 59 return 5; 60 else { 61 if (int n = 2 * k - 4) { 62 return n + 1; 63 return 2; 64 } 65 } 66 } // expected-note 2{{control reached end of constexpr function}} 67 static_assert(j(0) == -3, ""); 68 static_assert(j(1) == 5, ""); 69 static_assert(j(2), ""); // expected-error {{constant expression}} expected-note {{in call to 'j(2)'}} 70 static_assert(j(3) == 3, ""); 71 static_assert(j(4) == 5, ""); 72 static_assert(j(5) == 1, ""); 73 74 // There can be 0 return-statements. 75 constexpr void k() { 76 } 77 78 // If the return type is not 'void', no return statements => never a constant 79 // expression, so still diagnose that case. 80 [[noreturn]] constexpr int fn() { // expected-error {{no return statement in constexpr function}} 81 fn(); 82 } 83 84 // We evaluate the body of a constexpr constructor, to check for side-effects. 85 struct U { 86 constexpr U(int n) { 87 if (j(n)) {} // expected-note {{in call to 'j(2)'}} 88 } 89 }; 90 constexpr U u1{1}; 91 constexpr U u2{2}; // expected-error {{constant expression}} expected-note {{in call to 'U(2)'}} 92 93 // We allow expression-statements. 94 constexpr int l(bool b) { 95 if (b) 96 throw "invalid value for b!"; // expected-note {{subexpression not valid}} 97 return 5; 98 } 99 static_assert(l(false) == 5, ""); 100 static_assert(l(true), ""); // expected-error {{constant expression}} expected-note {{in call to 'l(true)'}} 101 102 // Potential constant expression checking is still applied where possible. 103 constexpr int htonl(int x) { // expected-error {{never produces a constant expression}} 104 typedef unsigned char uchar; 105 uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) }; 106 return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}} 107 } 108 109 constexpr int maybe_htonl(bool isBigEndian, int x) { 110 if (isBigEndian) 111 return x; 112 113 typedef unsigned char uchar; 114 uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) }; 115 return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}} 116 } 117 118 constexpr int swapped = maybe_htonl(false, 123); // expected-error {{constant expression}} expected-note {{in call}} 119 120 namespace NS { 121 constexpr int n = 0; 122 } 123 constexpr int namespace_alias() { 124 namespace N = NS; 125 return N::n; 126 } 127 128 namespace assign { 129 constexpr int a = 0; 130 const int b = 0; 131 int c = 0; // expected-note {{here}} 132 133 constexpr void set(const int &a, int b) { 134 const_cast<int&>(a) = b; // expected-note 3{{constant expression cannot modify an object that is visible outside that expression}} 135 } 136 constexpr int wrap(int a, int b) { 137 set(a, b); 138 return a; 139 } 140 141 static_assert((set(a, 1), a) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(a, 1)'}} 142 static_assert((set(b, 1), b) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(b, 1)'}} 143 static_assert((set(c, 1), c) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(c, 1)'}} 144 145 static_assert(wrap(a, 1) == 1, ""); 146 static_assert(wrap(b, 1) == 1, ""); 147 static_assert(wrap(c, 1) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} 148 } 149 150 namespace string_assign { 151 template<typename T> 152 constexpr void swap(T &a, T &b) { 153 T tmp = a; 154 a = b; 155 b = tmp; 156 } 157 template<typename Iterator> 158 constexpr void reverse(Iterator begin, Iterator end) { 159 while (begin != end && begin != --end) 160 swap(*begin++, *end); 161 } 162 template<typename Iterator1, typename Iterator2> 163 constexpr bool equal(Iterator1 a, Iterator1 ae, Iterator2 b, Iterator2 be) { 164 while (a != ae && b != be) 165 if (*a++ != *b++) 166 return false; 167 return a == ae && b == be; 168 } 169 constexpr bool test1(int n) { 170 char stuff[100] = "foobarfoo"; 171 const char stuff2[100] = "oofraboof"; 172 reverse(stuff, stuff + n); // expected-note {{cannot refer to element 101 of array of 100 elements}} 173 return equal(stuff, stuff + n, stuff2, stuff2 + n); 174 } 175 static_assert(!test1(1), ""); 176 static_assert(test1(3), ""); 177 static_assert(!test1(6), ""); 178 static_assert(test1(9), ""); 179 static_assert(!test1(100), ""); 180 static_assert(!test1(101), ""); // expected-error {{constant expression}} expected-note {{in call to 'test1(101)'}} 181 182 constexpr void f() { // expected-error{{constexpr function never produces a constant expression}} expected-note@+2{{assignment to dereferenced one-past-the-end pointer is not allowed in a constant expression}} 183 char foo[10] = { "z" }; // expected-note {{here}} 184 foo[10] = 'x'; // expected-warning {{past the end}} 185 } 186 } 187 188 namespace array_resize { 189 constexpr int do_stuff(int k1, int k2) { 190 int arr[1234] = { 1, 2, 3, 4 }; 191 arr[k1] = 5; // expected-note {{past-the-end}} expected-note {{cannot refer to element 1235}} expected-note {{cannot refer to element -1}} 192 return arr[k2]; 193 } 194 static_assert(do_stuff(1, 2) == 3, ""); 195 static_assert(do_stuff(0, 0) == 5, ""); 196 static_assert(do_stuff(1233, 1233) == 5, ""); 197 static_assert(do_stuff(1233, 0) == 1, ""); 198 static_assert(do_stuff(1234, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 199 static_assert(do_stuff(1235, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 200 static_assert(do_stuff(-1, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 201 } 202 203 namespace potential_const_expr { 204 constexpr void set(int &n) { n = 1; } 205 constexpr int div_zero_1() { int z = 0; set(z); return 100 / z; } // no error 206 constexpr int div_zero_2() { // expected-error {{never produces a constant expression}} 207 int z = 0; 208 return 100 / (set(z), 0); // expected-note {{division by zero}} 209 } 210 int n; // expected-note {{declared here}} 211 constexpr int ref() { // expected-error {{never produces a constant expression}} 212 int &r = n; 213 return r; // expected-note {{read of non-const variable 'n'}} 214 } 215 } 216 217 namespace subobject { 218 union A { constexpr A() : y(5) {} int x, y; }; 219 struct B { A a; }; 220 struct C : B {}; 221 union D { constexpr D() : c() {} constexpr D(int n) : n(n) {} C c; int n; }; 222 constexpr void f(D &d) { 223 d.c.a.y = 3; 224 // expected-note@-1 {{cannot modify an object that is visible outside}} 225 // expected-note@-2 {{assignment to member 'c' of union with active member 'n'}} 226 } 227 constexpr bool check(D &d) { return d.c.a.y == 3; } 228 229 constexpr bool g() { D d; f(d); return d.c.a.y == 3; } 230 static_assert(g(), ""); 231 232 D d; 233 constexpr bool h() { f(d); return check(d); } // expected-note {{in call}} 234 static_assert(h(), ""); // expected-error {{constant expression}} expected-note {{in call}} 235 236 constexpr bool i() { D d(0); f(d); return check(d); } // expected-note {{in call}} 237 static_assert(i(), ""); // expected-error {{constant expression}} expected-note {{in call}} 238 239 constexpr bool j() { D d; d.c.a.x = 3; return check(d); } // expected-note {{assignment to member 'x' of union with active member 'y'}} 240 static_assert(j(), ""); // expected-error {{constant expression}} expected-note {{in call}} 241 } 242 243 namespace lifetime { 244 constexpr int &&id(int &&n) { return static_cast<int&&>(n); } 245 constexpr int &&dead() { return id(0); } // expected-note {{temporary created here}} 246 constexpr int bad() { int &&n = dead(); n = 1; return n; } // expected-note {{assignment to temporary whose lifetime has ended}} 247 static_assert(bad(), ""); // expected-error {{constant expression}} expected-note {{in call}} 248 } 249 250 namespace const_modify { 251 constexpr int modify(int &n) { return n = 1; } // expected-note 2 {{modification of object of const-qualified type 'const int'}} 252 constexpr int test1() { int k = 0; return modify(k); } 253 constexpr int test2() { const int k = 0; return modify(const_cast<int&>(k)); } // expected-note 2 {{in call}} 254 static_assert(test1() == 1, ""); 255 static_assert(test2() == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 256 constexpr int i = test2(); // expected-error {{constant expression}} expected-note {{in call}} 257 } 258 259 namespace null { 260 constexpr int test(int *p) { 261 return *p = 123; // expected-note {{assignment to dereferenced null pointer}} 262 } 263 static_assert(test(0), ""); // expected-error {{constant expression}} expected-note {{in call}} 264 } 265 266 namespace incdec { 267 template<typename T> constexpr T &ref(T &&r) { return r; } 268 template<typename T> constexpr T postinc(T &&r) { return (r++, r); } 269 template<typename T> constexpr T postdec(T &&r) { return (r--, r); } 270 271 static_assert(++ref(0) == 1, ""); 272 static_assert(ref(0)++ == 0, ""); 273 static_assert(postinc(0) == 1, ""); 274 static_assert(--ref(0) == -1, ""); 275 static_assert(ref(0)-- == 0, ""); 276 static_assert(postdec(0) == -1, ""); 277 278 constexpr int overflow_int_inc_1 = ref(0x7fffffff)++; // expected-error {{constant}} expected-note {{2147483648}} 279 constexpr int overflow_int_inc_1_ok = ref(0x7ffffffe)++; 280 constexpr int overflow_int_inc_2 = ++ref(0x7fffffff); // expected-error {{constant}} expected-note {{2147483648}} 281 constexpr int overflow_int_inc_2_ok = ++ref(0x7ffffffe); 282 283 // inc/dec on short can't overflow because we promote to int first 284 static_assert(++ref<short>(0x7fff) == (int)0xffff8000u, ""); 285 static_assert(--ref<short>(0x8000) == 0x7fff, ""); 286 287 // inc on bool sets to true 288 static_assert(++ref(false), ""); // expected-warning {{deprecated}} 289 static_assert(++ref(true), ""); // expected-warning {{deprecated}} 290 291 int arr[10]; 292 static_assert(++ref(&arr[0]) == &arr[1], ""); 293 static_assert(++ref(&arr[9]) == &arr[10], ""); 294 static_assert(++ref(&arr[10]) == &arr[11], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} 295 static_assert(ref(&arr[0])++ == &arr[0], ""); 296 static_assert(ref(&arr[10])++ == &arr[10], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} 297 static_assert(postinc(&arr[0]) == &arr[1], ""); 298 static_assert(--ref(&arr[10]) == &arr[9], ""); 299 static_assert(--ref(&arr[1]) == &arr[0], ""); 300 static_assert(--ref(&arr[0]) != &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} 301 static_assert(ref(&arr[1])-- == &arr[1], ""); 302 static_assert(ref(&arr[0])-- == &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} 303 static_assert(postdec(&arr[1]) == &arr[0], ""); 304 305 int x; 306 static_assert(++ref(&x) == &x + 1, ""); 307 308 static_assert(++ref(0.0) == 1.0, ""); 309 static_assert(ref(0.0)++ == 0.0, ""); 310 static_assert(postinc(0.0) == 1.0, ""); 311 static_assert(--ref(0.0) == -1.0, ""); 312 static_assert(ref(0.0)-- == 0.0, ""); 313 static_assert(postdec(0.0) == -1.0, ""); 314 315 static_assert(++ref(1e100) == 1e100, ""); 316 static_assert(--ref(1e100) == 1e100, ""); 317 318 union U { 319 int a, b; 320 }; 321 constexpr int f(U u) { 322 return ++u.b; // expected-note {{increment of member 'b' of union with active member 'a'}} 323 } 324 constexpr int wrong_member = f({0}); // expected-error {{constant}} expected-note {{in call to 'f({.a = 0})'}} 325 constexpr int vol = --ref<volatile int>(0); // expected-error {{constant}} expected-note {{decrement of volatile-qualified}} 326 327 constexpr int incr(int k) { 328 int x = k; 329 if (x++ == 100) 330 return x; 331 return incr(x); 332 } 333 static_assert(incr(0) == 101, ""); 334 } 335 336 namespace compound_assign { 337 constexpr bool test_int() { 338 int a = 3; 339 a += 6; 340 if (a != 9) return false; 341 a -= 2; 342 if (a != 7) return false; 343 a *= 3; 344 if (a != 21) return false; 345 if (&(a /= 10) != &a) return false; 346 if (a != 2) return false; 347 a <<= 3; 348 if (a != 16) return false; 349 a %= 6; 350 if (a != 4) return false; 351 a >>= 1; 352 if (a != 2) return false; 353 a ^= 10; 354 if (a != 8) return false; 355 a |= 5; 356 if (a != 13) return false; 357 a &= 14; 358 if (a != 12) return false; 359 return true; 360 } 361 static_assert(test_int(), ""); 362 363 constexpr bool test_float() { 364 float f = 123.; 365 f *= 2; 366 if (f != 246.) return false; 367 if ((f -= 0.5) != 245.5) return false; 368 if (f != 245.5) return false; 369 f /= 0.5; 370 if (f != 491.) return false; 371 f += -40; 372 if (f != 451.) return false; 373 return true; 374 } 375 static_assert(test_float(), ""); 376 377 constexpr bool test_ptr() { 378 int arr[123] = {}; 379 int *p = arr; 380 if ((p += 4) != &arr[4]) return false; 381 if (p != &arr[4]) return false; 382 p += -1; 383 if (p != &arr[3]) return false; 384 if ((p -= -10) != &arr[13]) return false; 385 if (p != &arr[13]) return false; 386 p -= 11; 387 if (p != &arr[2]) return false; 388 return true; 389 } 390 static_assert(test_ptr(), ""); 391 392 template<typename T> 393 constexpr bool test_overflow() { 394 T a = 1; 395 while (a != a / 2) 396 a *= 2; // expected-note {{value 2147483648 is outside the range}} expected-note {{ 9223372036854775808 }} expected-note {{floating point arithmetic produces an infinity}} 397 return true; 398 } 399 400 static_assert(test_overflow<int>(), ""); // expected-error {{constant}} expected-note {{call}} 401 static_assert(test_overflow<unsigned>(), ""); // ok, unsigned overflow is defined 402 static_assert(test_overflow<short>(), ""); // ok, short is promoted to int before multiplication 403 static_assert(test_overflow<unsigned short>(), ""); // ok 404 static_assert(test_overflow<unsigned long long>(), ""); // ok 405 static_assert(test_overflow<long long>(), ""); // expected-error {{constant}} expected-note {{call}} 406 static_assert(test_overflow<float>(), ""); // expected-error {{constant}} expected-note {{call}} 407 408 constexpr short test_promotion(short k) { 409 short s = k; 410 s *= s; 411 return s; 412 } 413 static_assert(test_promotion(100) == 10000, ""); 414 static_assert(test_promotion(200) == -25536, ""); 415 static_assert(test_promotion(256) == 0, ""); 416 417 constexpr const char *test_bounds(const char *p, int o) { 418 return p += o; // expected-note {{element 5 of}} expected-note {{element -1 of}} expected-note {{element 1000 of}} 419 } 420 static_assert(test_bounds("foo", 0)[0] == 'f', ""); 421 static_assert(test_bounds("foo", 3)[0] == 0, ""); 422 static_assert(test_bounds("foo", 4)[-3] == 'o', ""); 423 static_assert(test_bounds("foo" + 4, -4)[0] == 'f', ""); 424 static_assert(test_bounds("foo", 5) != 0, ""); // expected-error {{constant}} expected-note {{call}} 425 static_assert(test_bounds("foo", -1) != 0, ""); // expected-error {{constant}} expected-note {{call}} 426 static_assert(test_bounds("foo", 1000) != 0, ""); // expected-error {{constant}} expected-note {{call}} 427 } 428 429 namespace loops { 430 constexpr int fib_loop(int a) { 431 int f_k = 0, f_k_plus_one = 1; 432 for (int k = 1; k != a; ++k) { 433 int f_k_plus_two = f_k + f_k_plus_one; 434 f_k = f_k_plus_one; 435 f_k_plus_one = f_k_plus_two; 436 } 437 return f_k_plus_one; 438 } 439 static_assert(fib_loop(46) == 1836311903, ""); 440 441 constexpr bool breaks_work() { 442 int a = 0; 443 for (int n = 0; n != 100; ++n) { 444 ++a; 445 if (a == 5) continue; 446 if ((a % 5) == 0) break; 447 } 448 449 int b = 0; 450 while (b != 17) { 451 ++b; 452 if (b == 6) continue; 453 if ((b % 6) == 0) break; 454 } 455 456 int c = 0; 457 do { 458 ++c; 459 if (c == 7) continue; 460 if ((c % 7) == 0) break; 461 } while (c != 21); 462 463 return a == 10 && b == 12 && c == 14; 464 } 465 static_assert(breaks_work(), ""); 466 467 void not_constexpr(); 468 constexpr bool no_cont_after_break() { 469 for (;;) { 470 break; 471 not_constexpr(); 472 } 473 while (true) { 474 break; 475 not_constexpr(); 476 } 477 do { 478 break; 479 not_constexpr(); 480 } while (true); 481 return true; 482 } 483 static_assert(no_cont_after_break(), ""); 484 485 constexpr bool cond() { 486 for (int a = 1; bool b = a != 3; ++a) { 487 if (!b) 488 return false; 489 } 490 while (bool b = true) { 491 b = false; 492 break; 493 } 494 return true; 495 } 496 static_assert(cond(), ""); 497 498 constexpr int range_for() { 499 int arr[] = { 1, 2, 3, 4, 5 }; 500 int sum = 0; 501 for (int x : arr) 502 sum += x; 503 return sum; 504 } 505 static_assert(range_for() == 15, ""); 506 507 template<int...N> struct ints {}; 508 template<typename A, typename B> struct join_ints; 509 template<int...As, int...Bs> struct join_ints<ints<As...>, ints<Bs...>> { 510 using type = ints<As..., sizeof...(As) + Bs...>; 511 }; 512 template<unsigned N> struct make_ints { 513 using type = typename join_ints<typename make_ints<N/2>::type, typename make_ints<(N+1)/2>::type>::type; 514 }; 515 template<> struct make_ints<0> { using type = ints<>; }; 516 template<> struct make_ints<1> { using type = ints<0>; }; 517 518 struct ignore { template<typename ...Ts> constexpr ignore(Ts &&...) {} }; 519 520 template<typename T, unsigned N> struct array { 521 constexpr array() : arr{} {} 522 template<typename ...X> 523 constexpr array(X ...x) : arr{} { 524 init(typename make_ints<sizeof...(X)>::type{}, x...); 525 } 526 template<int ...I, typename ...X> constexpr void init(ints<I...>, X ...x) { 527 ignore{arr[I] = x ...}; 528 } 529 T arr[N]; 530 struct iterator { 531 T *p; 532 constexpr explicit iterator(T *p) : p(p) {} 533 constexpr bool operator!=(iterator o) { return p != o.p; } 534 constexpr iterator &operator++() { ++p; return *this; } 535 constexpr T &operator*() { return *p; } 536 }; 537 constexpr iterator begin() { return iterator(arr); } 538 constexpr iterator end() { return iterator(arr + N); } 539 }; 540 541 constexpr int range_for_2() { 542 array<int, 5> arr { 1, 2, 3, 4, 5 }; 543 int sum = 0; 544 for (int k : arr) { 545 sum += k; 546 if (sum > 8) break; 547 } 548 return sum; 549 } 550 static_assert(range_for_2() == 10, ""); 551 } 552 553 namespace assignment_op { 554 struct A { 555 constexpr A() : n(5) {} 556 int n; 557 struct B { 558 int k = 1; 559 union U { 560 constexpr U() : y(4) {} 561 int x; 562 int y; 563 } u; 564 } b; 565 }; 566 constexpr bool testA() { 567 A a, b; 568 a.n = 7; 569 a.b.u.y = 5; 570 b = a; 571 return b.n == 7 && b.b.u.y == 5 && b.b.k == 1; 572 } 573 static_assert(testA(), ""); 574 575 struct B { 576 bool assigned = false; 577 constexpr B &operator=(const B&) { 578 assigned = true; 579 return *this; 580 } 581 }; 582 struct C : B { 583 B b; 584 int n = 5; 585 }; 586 constexpr bool testC() { 587 C c, d; 588 c.n = 7; 589 d = c; 590 c.n = 3; 591 return d.n == 7 && d.assigned && d.b.assigned; 592 } 593 static_assert(testC(), ""); 594 } 595 596 namespace switch_stmt { 597 constexpr int f(char k) { 598 bool b = false; 599 int z = 6; 600 switch (k) { 601 return -1; 602 case 0: 603 if (false) { 604 case 1: 605 z = 1; 606 for (; b;) { 607 return 5; 608 while (0) 609 case 2: return 2; 610 case 7: z = 7; 611 do case 6: { 612 return z; 613 if (false) 614 case 3: return 3; 615 case 4: z = 4; 616 } while (1); 617 case 5: b = true; 618 case 9: z = 9; 619 } 620 return z; 621 } else if (false) case 8: z = 8; 622 else if (false) { 623 case 10: 624 z = -10; 625 break; 626 } 627 else z = 0; 628 return z; 629 default: 630 return -1; 631 } 632 return -z; 633 } 634 static_assert(f(0) == 0, ""); 635 static_assert(f(1) == 1, ""); 636 static_assert(f(2) == 2, ""); 637 static_assert(f(3) == 3, ""); 638 static_assert(f(4) == 4, ""); 639 static_assert(f(5) == 5, ""); 640 static_assert(f(6) == 6, ""); 641 static_assert(f(7) == 7, ""); 642 static_assert(f(8) == 8, ""); 643 static_assert(f(9) == 9, ""); 644 static_assert(f(10) == 10, ""); 645 646 // Check that we can continue an outer loop from within a switch. 647 constexpr bool contin() { 648 for (int n = 0; n != 10; ++n) { 649 switch (n) { 650 case 0: 651 ++n; 652 continue; 653 case 1: 654 return false; 655 case 2: 656 return true; 657 } 658 } 659 return false; 660 } 661 static_assert(contin(), ""); 662 663 constexpr bool switch_into_for() { 664 int n = 0; 665 switch (n) { 666 for (; n == 1; ++n) { 667 return n == 1; 668 case 0: ; 669 } 670 } 671 return false; 672 } 673 static_assert(switch_into_for(), ""); 674 675 constexpr void duff_copy(char *a, const char *b, int n) { 676 switch ((n - 1) % 8 + 1) { 677 for ( ; n; n = (n - 1) & ~7) { 678 case 8: a[n-8] = b[n-8]; 679 case 7: a[n-7] = b[n-7]; 680 case 6: a[n-6] = b[n-6]; 681 case 5: a[n-5] = b[n-5]; 682 case 4: a[n-4] = b[n-4]; 683 case 3: a[n-3] = b[n-3]; 684 case 2: a[n-2] = b[n-2]; 685 case 1: a[n-1] = b[n-1]; 686 } 687 case 0: ; 688 } 689 } 690 691 constexpr bool test_copy(const char *str, int n) { 692 char buffer[16] = {}; 693 duff_copy(buffer, str, n); 694 for (int i = 0; i != sizeof(buffer); ++i) 695 if (buffer[i] != (i < n ? str[i] : 0)) 696 return false; 697 return true; 698 } 699 static_assert(test_copy("foo", 0), ""); 700 static_assert(test_copy("foo", 1), ""); 701 static_assert(test_copy("foo", 2), ""); 702 static_assert(test_copy("hello world", 0), ""); 703 static_assert(test_copy("hello world", 7), ""); 704 static_assert(test_copy("hello world", 8), ""); 705 static_assert(test_copy("hello world", 9), ""); 706 static_assert(test_copy("hello world", 10), ""); 707 static_assert(test_copy("hello world", 10), ""); 708 } 709 710 namespace deduced_return_type { 711 constexpr auto f() { return 0; } 712 template<typename T> constexpr auto g(T t) { return t; } 713 static_assert(f() == 0, ""); 714 static_assert(g(true), ""); 715 } 716 717 namespace modify_temporary_during_construction { 718 struct A { int &&temporary; int x; int y; }; 719 constexpr int f(int &r) { r *= 9; return r - 12; } 720 constexpr A a = { 6, f(a.temporary), a.temporary }; // expected-note {{temporary created here}} 721 static_assert(a.x == 42, ""); 722 static_assert(a.y == 54, ""); 723 constexpr int k = a.temporary++; // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}} 724 } 725 726 namespace std { 727 typedef decltype(sizeof(int)) size_t; 728 729 template <class _E> 730 class initializer_list 731 { 732 const _E* __begin_; 733 size_t __size_; 734 735 constexpr initializer_list(const _E* __b, size_t __s) 736 : __begin_(__b), 737 __size_(__s) 738 {} 739 740 public: 741 typedef _E value_type; 742 typedef const _E& reference; 743 typedef const _E& const_reference; 744 typedef size_t size_type; 745 746 typedef const _E* iterator; 747 typedef const _E* const_iterator; 748 749 constexpr initializer_list() : __begin_(nullptr), __size_(0) {} 750 751 constexpr size_t size() const {return __size_;} 752 constexpr const _E* begin() const {return __begin_;} 753 constexpr const _E* end() const {return __begin_ + __size_;} 754 }; 755 } 756 757 namespace InitializerList { 758 constexpr int sum(std::initializer_list<int> ints) { 759 int total = 0; 760 for (int n : ints) total += n; 761 return total; 762 } 763 static_assert(sum({1, 2, 3, 4, 5}) == 15, ""); 764 } 765 766 namespace StmtExpr { 767 constexpr int f(int k) { 768 switch (k) { 769 case 0: 770 return 0; 771 772 ({ 773 case 1: // expected-note {{not supported}} 774 return 1; 775 }); 776 } 777 } 778 static_assert(f(1) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 779 780 constexpr int g() { // expected-error {{never produces a constant}} 781 return ({ int n; n; }); // expected-note {{object of type 'int' is not initialized}} 782 } 783 784 // FIXME: We should handle the void statement expression case. 785 constexpr int h() { // expected-error {{never produces a constant}} 786 ({ if (true) {} }); // expected-note {{not supported}} 787 return 0; 788 } 789 } 790 791 namespace VirtualFromBase { 792 struct S1 { 793 virtual int f() const; 794 }; 795 struct S2 { 796 virtual int f(); 797 }; 798 template <typename T> struct X : T { 799 constexpr X() {} 800 double d = 0.0; 801 constexpr int f() { return sizeof(T); } 802 }; 803 804 // Non-virtual f(), OK. 805 constexpr X<X<S1>> xxs1; 806 constexpr X<S1> *p = const_cast<X<X<S1>>*>(&xxs1); 807 static_assert(p->f() == sizeof(S1), ""); 808 809 // Virtual f(), not OK. 810 constexpr X<X<S2>> xxs2; 811 constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2); 812 static_assert(q->f() == sizeof(X<S2>), ""); // expected-error {{constant expression}} expected-note {{virtual function call}} 813 } 814 815 namespace Lifetime { 816 constexpr int &get(int &&r) { return r; } 817 constexpr int f() { 818 int &r = get(123); 819 return r; // expected-note {{read of object outside its lifetime}} 820 } 821 static_assert(f() == 123, ""); // expected-error {{constant expression}} expected-note {{in call}} 822 823 constexpr int g() { 824 int *p = 0; 825 { 826 int n = 0; 827 p = &n; 828 n = 42; 829 } 830 *p = 123; // expected-note {{assignment to object outside its lifetime}} 831 return *p; 832 } 833 static_assert(g() == 42, ""); // expected-error {{constant expression}} expected-note {{in call}} 834 835 constexpr int h(int n) { 836 int *p[4] = {}; 837 int &&r = 1; 838 p[0] = &r; 839 while (int a = 1) { 840 p[1] = &a; 841 for (int b = 1; int c = 1; ) { 842 p[2] = &b, p[3] = &c; 843 break; 844 } 845 break; 846 } 847 *p[n] = 0; // expected-note 3{{assignment to object outside its lifetime}} 848 return *p[n]; 849 } 850 static_assert(h(0) == 0, ""); // ok, lifetime-extended 851 static_assert(h(1) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}} 852 static_assert(h(2) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}} 853 static_assert(h(3) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}} 854 855 // FIXME: This function should be treated as non-constant. 856 constexpr void lifetime_versus_loops() { 857 int *p = 0; 858 for (int i = 0; i != 2; ++i) { 859 int *q = p; 860 int n = 0; 861 p = &n; 862 if (i) 863 // This modifies the 'n' from the previous iteration of the loop outside 864 // its lifetime. 865 ++*q; 866 } 867 } 868 static_assert((lifetime_versus_loops(), true), ""); 869 } 870 871 namespace Bitfields { 872 struct A { 873 bool b : 1; 874 int n : 4; 875 unsigned u : 5; 876 }; 877 constexpr bool test() { 878 A a {}; 879 a.b += 2; 880 --a.n; 881 --a.u; 882 a.n = -a.n * 3; 883 return a.b == false && a.n == 3 && a.u == 31; 884 } 885 static_assert(test(), ""); 886 } 887 888 namespace PR17615 { 889 struct A { 890 int &&r; 891 constexpr A(int &&r) : r(static_cast<int &&>(r)) {} 892 constexpr A() : A(0) { 893 (void)+r; // expected-note {{outside its lifetime}} 894 } 895 }; 896 constexpr int k = A().r; // expected-error {{constant expression}} expected-note {{in call to}} 897 } 898 899 namespace PR17331 { 900 template<typename T, unsigned int N> 901 constexpr T sum(const T (&arr)[N]) { 902 T result = 0; 903 for (T i : arr) 904 result += i; 905 return result; 906 } 907 908 constexpr int ARR[] = { 1, 2, 3, 4, 5 }; 909 static_assert(sum(ARR) == 15, ""); 910 } 911 912 namespace EmptyClass { 913 struct E1 {} e1; 914 union E2 {} e2; // expected-note 4{{here}} 915 struct E3 : E1 {} e3; 916 917 template<typename E> 918 constexpr int f(E &a, int kind) { 919 switch (kind) { 920 case 0: { E e(a); return 0; } // expected-note {{read}} expected-note {{in call}} 921 case 1: { E e(static_cast<E&&>(a)); return 0; } // expected-note {{read}} expected-note {{in call}} 922 case 2: { E e; e = a; return 0; } // expected-note {{read}} expected-note {{in call}} 923 case 3: { E e; e = static_cast<E&&>(a); return 0; } // expected-note {{read}} expected-note {{in call}} 924 } 925 } 926 constexpr int test1 = f(e1, 0); 927 constexpr int test2 = f(e2, 0); // expected-error {{constant expression}} expected-note {{in call}} 928 constexpr int test3 = f(e3, 0); 929 constexpr int test4 = f(e1, 1); 930 constexpr int test5 = f(e2, 1); // expected-error {{constant expression}} expected-note {{in call}} 931 constexpr int test6 = f(e3, 1); 932 constexpr int test7 = f(e1, 2); 933 constexpr int test8 = f(e2, 2); // expected-error {{constant expression}} expected-note {{in call}} 934 constexpr int test9 = f(e3, 2); 935 constexpr int testa = f(e1, 3); 936 constexpr int testb = f(e2, 3); // expected-error {{constant expression}} expected-note {{in call}} 937 constexpr int testc = f(e3, 3); 938 } 939 940 namespace SpeculativeEvalWrites { 941 // Ensure that we don't try to speculatively evaluate writes. 942 constexpr int f() { 943 int i = 0; 944 int a = 0; 945 // __builtin_object_size speculatively evaluates its first argument. 946 __builtin_object_size((i = 1, &a), 0); 947 return i; 948 } 949 950 static_assert(!f(), ""); 951 } 952 953 namespace PR27989 { 954 constexpr int f(int n) { 955 int a = (n = 1, 0); 956 return n; 957 } 958 static_assert(f(0) == 1, ""); 959 } 960