1 // RUN: %clang_cc1 -std=c++23 -Werror=return-type -fsyntax-only -verify=expected,cxx20_23,cxx23 %s -fcxx-exceptions -triple=x86_64-linux-gnu 2 // RUN: %clang_cc1 -std=c++20 -Werror=return-type -fsyntax-only -verify=expected,cxx14_20,cxx20_23,cxx20 %s -fcxx-exceptions -triple=x86_64-linux-gnu 3 // RUN: %clang_cc1 -std=c++14 -Werror=return-type -fsyntax-only -verify=expected,cxx14_20,cxx14 %s -fcxx-exceptions -triple=x86_64-linux-gnu 4 5 struct S { 6 // dummy ctor to make this a literal type 7 constexpr S(int); 8 9 S(); 10 11 int arr[10]; 12 13 constexpr int &get(int n) { return arr[n]; } 14 constexpr const int &get(int n) const { return arr[n]; } 15 }; 16 17 S s = S(); 18 const S &sr = s; 19 static_assert(&s.get(4) - &sr.get(2) == 2, ""); 20 21 // Compound-statements can be used in constexpr functions. 22 constexpr int e() {{{{}} return 5; }} 23 static_assert(e() == 5, ""); 24 25 // Types can be defined in constexpr functions. 26 constexpr int f() { 27 enum E { e1, e2, e3 }; 28 29 struct S { 30 constexpr S(E e) : e(e) {} 31 constexpr int get() { return e; } 32 E e; 33 }; 34 35 return S(e2).get(); 36 } 37 static_assert(f() == 1, ""); 38 39 // Variables can be declared in constexpr functions. 40 constexpr int g(int k) { 41 const int n = 9; 42 int k2 = k * k; 43 int k3 = k2 * k; 44 return 3 * k3 + 5 * k2 + n * k - 20; 45 } 46 static_assert(g(2) == 42, ""); 47 constexpr int h(int n) { // cxx14_20-error {{constexpr function never produces a constant expression}} 48 static const int m = n; // cxx14_20-note {{control flows through the definition of a static variable}} \ 49 // cxx14_20-warning {{definition of a static variable in a constexpr function is a C++23 extension}} 50 return m; 51 } 52 constexpr int i(int n) { // cxx14_20-error {{constexpr function never produces a constant expression}} 53 thread_local const int m = n; // cxx14_20-note {{control flows through the definition of a thread_local variable}} \ 54 // cxx14_20-warning {{definition of a thread_local variable in a constexpr function is a C++23 extension}} 55 return m; 56 } 57 58 // if-statements can be used in constexpr functions. 59 constexpr int j(int k) { 60 if (k == 5) 61 return 1; 62 if (k == 1) 63 return 5; 64 else { 65 if (int n = 2 * k - 4) { 66 return n + 1; 67 return 2; 68 } 69 } 70 } // expected-note 2{{control reached end of constexpr function}} 71 // cxx23-error@-1 {{does not return a value in all control paths}} 72 static_assert(j(0) == -3, ""); 73 static_assert(j(1) == 5, ""); 74 static_assert(j(2), ""); // expected-error {{constant expression}} expected-note {{in call to 'j(2)'}} 75 static_assert(j(3) == 3, ""); 76 static_assert(j(4) == 5, ""); 77 static_assert(j(5) == 1, ""); 78 79 // There can be 0 return-statements. 80 constexpr void k() { 81 } 82 83 // If the return type is not 'void', no return statements => never a constant 84 // expression, so still diagnose that case. 85 [[noreturn]] constexpr int fn() { // cxx14_20-error {{no return statement in constexpr function}} 86 fn(); 87 } 88 89 // We evaluate the body of a constexpr constructor, to check for side-effects. 90 struct U { 91 constexpr U(int n) { 92 if (j(n)) {} // expected-note {{in call to 'j(2)'}} 93 } 94 }; 95 constexpr U u1{1}; 96 constexpr U u2{2}; // expected-error {{constant expression}} expected-note {{in call to 'U(2)'}} 97 98 // We allow expression-statements. 99 constexpr int l(bool b) { 100 if (b) 101 throw "invalid value for b!"; // expected-note {{subexpression not valid}} 102 return 5; 103 } 104 static_assert(l(false) == 5, ""); 105 static_assert(l(true), ""); // expected-error {{constant expression}} expected-note {{in call to 'l(true)'}} 106 107 // Potential constant expression checking is still applied where possible. 108 constexpr int htonl(int x) { // cxx14_20-error {{never produces a constant expression}} 109 typedef unsigned char uchar; 110 uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) }; 111 return *reinterpret_cast<int*>(arr); // cxx14_20-note {{reinterpret_cast is not allowed in a constant expression}} 112 } 113 114 constexpr int maybe_htonl(bool isBigEndian, int x) { 115 if (isBigEndian) 116 return x; 117 118 typedef unsigned char uchar; 119 uchar arr[4] = { uchar(x >> 24), uchar(x >> 16), uchar(x >> 8), uchar(x) }; 120 return *reinterpret_cast<int*>(arr); // expected-note {{reinterpret_cast is not allowed in a constant expression}} 121 } 122 123 constexpr int swapped = maybe_htonl(false, 123); // expected-error {{constant expression}} expected-note {{in call}} 124 125 namespace NS { 126 constexpr int n = 0; 127 } 128 constexpr int namespace_alias() { 129 namespace N = NS; 130 return N::n; 131 } 132 133 namespace assign { 134 constexpr int a = 0; 135 const int b = 0; 136 int c = 0; // expected-note {{here}} 137 138 constexpr void set(const int &a, int b) { 139 const_cast<int&>(a) = b; // expected-note 3{{constant expression cannot modify an object that is visible outside that expression}} 140 } 141 constexpr int wrap(int a, int b) { 142 set(a, b); 143 return a; 144 } 145 146 static_assert((set(a, 1), a) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(a, 1)'}} 147 static_assert((set(b, 1), b) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(b, 1)'}} 148 static_assert((set(c, 1), c) == 1, ""); // expected-error {{constant expression}} expected-note {{in call to 'set(c, 1)'}} 149 150 static_assert(wrap(a, 1) == 1, ""); 151 static_assert(wrap(b, 1) == 1, ""); 152 static_assert(wrap(c, 1) == 1, ""); // expected-error {{constant expression}} expected-note {{read of non-const variable 'c'}} 153 } 154 155 namespace string_assign { 156 template<typename T> 157 constexpr void swap(T &a, T &b) { 158 T tmp = a; 159 a = b; 160 b = tmp; 161 } 162 template<typename Iterator> 163 constexpr void reverse(Iterator begin, Iterator end) { 164 while (begin != end && begin != --end) 165 swap(*begin++, *end); 166 } 167 template<typename Iterator1, typename Iterator2> 168 constexpr bool equal(Iterator1 a, Iterator1 ae, Iterator2 b, Iterator2 be) { 169 while (a != ae && b != be) 170 if (*a++ != *b++) 171 return false; 172 return a == ae && b == be; 173 } 174 constexpr bool test1(int n) { 175 char stuff[100] = "foobarfoo"; 176 const char stuff2[100] = "oofraboof"; 177 reverse(stuff, stuff + n); // expected-note {{cannot refer to element 101 of array of 100 elements}} 178 return equal(stuff, stuff + n, stuff2, stuff2 + n); 179 } 180 static_assert(!test1(1), ""); 181 static_assert(test1(3), ""); 182 static_assert(!test1(6), ""); 183 static_assert(test1(9), ""); 184 static_assert(!test1(100), ""); 185 static_assert(!test1(101), ""); // expected-error {{constant expression}} expected-note {{in call to 'test1(101)'}} 186 187 constexpr void f() { // cxx14_20-error{{constexpr function never produces a constant expression}} cxx14_20-note@+2{{assignment to dereferenced one-past-the-end pointer is not allowed in a constant expression}} 188 char foo[10] = { "z" }; // expected-note {{here}} 189 foo[10] = 'x'; // expected-warning {{past the end}} 190 } 191 } 192 193 namespace array_resize { 194 constexpr int do_stuff(int k1, int k2) { 195 int arr[1234] = { 1, 2, 3, 4 }; 196 arr[k1] = 5; // expected-note {{past-the-end}} expected-note {{cannot refer to element 1235}} expected-note {{cannot refer to element -1}} 197 return arr[k2]; 198 } 199 static_assert(do_stuff(1, 2) == 3, ""); 200 static_assert(do_stuff(0, 0) == 5, ""); 201 static_assert(do_stuff(1233, 1233) == 5, ""); 202 static_assert(do_stuff(1233, 0) == 1, ""); 203 static_assert(do_stuff(1234, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 204 static_assert(do_stuff(1235, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 205 static_assert(do_stuff(-1, 0) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 206 } 207 208 namespace potential_const_expr { 209 constexpr void set(int &n) { n = 1; } 210 constexpr int div_zero_1() { int z = 0; set(z); return 100 / z; } // no error 211 constexpr int div_zero_2() { // cxx14_20-error {{never produces a constant expression}} 212 int z = 0; 213 return 100 / (set(z), 0); // cxx14_20-note {{division by zero}} 214 } 215 int n; // cxx14_20-note {{declared here}} 216 constexpr int ref() { // cxx14_20-error {{never produces a constant expression}} 217 int &r = n; 218 return r; // cxx14_20-note {{read of non-const variable 'n'}} 219 } 220 } 221 222 namespace subobject { 223 union A { constexpr A() : y(5) {} int x, y; }; 224 struct B { A a; }; 225 struct C : B {}; 226 union D { constexpr D() : c() {} constexpr D(int n) : n(n) {} C c; int n; }; 227 constexpr void f(D &d) { 228 d.c.a.y = 3; 229 // expected-note@-1 {{cannot modify an object that is visible outside}} 230 // expected-note@-2 {{assignment to member 'c' of union with active member 'n'}} 231 } 232 constexpr bool check(D &d) { return d.c.a.y == 3; } 233 // cxx20_23-note@-1 {{read of member 'y' of union with active member 'x'}} 234 235 constexpr bool g() { D d; f(d); return d.c.a.y == 3; } 236 static_assert(g(), ""); 237 238 D d; 239 constexpr bool h() { f(d); return check(d); } // expected-note {{in call}} 240 static_assert(h(), ""); // expected-error {{constant expression}} expected-note {{in call}} 241 242 constexpr bool i() { D d(0); f(d); return check(d); } // expected-note {{in call}} 243 static_assert(i(), ""); // expected-error {{constant expression}} expected-note {{in call}} 244 245 constexpr bool j() { D d; d.c.a.x = 3; return check(d); } // cxx14-note {{assignment to member 'x' of union with active member 'y'}} 246 // cxx20_23-note@-1 {{in call to 'check(d)'}} 247 static_assert(j(), ""); // expected-error {{constant expression}} expected-note {{in call}} 248 } 249 250 namespace lifetime { 251 constexpr int &&id(int &&n) { return static_cast<int&&>(n); } 252 constexpr int &&dead() { return id(0); } // expected-note {{temporary created here}} 253 constexpr int bad() { int &&n = dead(); n = 1; return n; } // expected-note {{assignment to temporary whose lifetime has ended}} 254 static_assert(bad(), ""); // expected-error {{constant expression}} expected-note {{in call}} 255 } 256 257 namespace const_modify { 258 constexpr int modify(int &n) { return n = 1; } // expected-note 2 {{modification of object of const-qualified type 'const int'}} 259 constexpr int test1() { int k = 0; return modify(k); } 260 constexpr int test2() { const int k = 0; return modify(const_cast<int&>(k)); } // expected-note 2 {{in call}} 261 static_assert(test1() == 1, ""); 262 static_assert(test2() == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 263 constexpr int i = test2(); // expected-error {{constant expression}} expected-note {{in call}} 264 } 265 266 namespace null { 267 constexpr int test(int *p) { 268 return *p = 123; // expected-note {{assignment to dereferenced null pointer}} 269 } 270 static_assert(test(0), ""); // expected-error {{constant expression}} expected-note {{in call}} 271 } 272 273 namespace incdec { 274 template<typename T> constexpr T &ref(T &&r) { return r; } 275 // cxx23-error@-1 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} 276 template<typename T> constexpr T postinc(T &&r) { return (r++, r); } 277 template<typename T> constexpr T postdec(T &&r) { return (r--, r); } 278 279 template int &ref<int>(int &&); 280 // cxx23-note@-1 {{in instantiation of function template specialization}} 281 282 static_assert(postinc(0) == 1, ""); 283 static_assert(postdec(0) == -1, ""); 284 #if __cplusplus <= 202002L 285 static_assert(++ref(0) == 1, ""); 286 static_assert(ref(0)++ == 0, ""); 287 static_assert(--ref(0) == -1, ""); 288 static_assert(ref(0)-- == 0, ""); 289 #endif 290 291 #if __cplusplus <= 202002L 292 constexpr int overflow_int_inc_1 = ref(0x7fffffff)++; // expected-error {{constant}} expected-note {{2147483648}} 293 constexpr int overflow_int_inc_1_ok = ref(0x7ffffffe)++; 294 constexpr int overflow_int_inc_2 = ++ref(0x7fffffff); // expected-error {{constant}} expected-note {{2147483648}} 295 constexpr int overflow_int_inc_2_ok = ++ref(0x7ffffffe); 296 297 // inc/dec on short can't overflow because we promote to int first 298 static_assert(++ref<short>(0x7fff) == (int)0xffff8000u, ""); 299 static_assert(--ref<short>(0x8000) == 0x7fff, ""); 300 301 // inc on bool sets to true 302 static_assert(++ref(false), ""); 303 // cxx14-warning@-1 {{incrementing expression of type bool}} 304 // cxx20-error@-2 {{incrementing expression of type bool}} 305 static_assert(++ref(true), ""); 306 // cxx14-warning@-1 {{incrementing expression of type bool}} 307 // cxx20-error@-2 {{incrementing expression of type bool}} 308 #endif 309 310 int arr[10]; 311 static_assert(postinc(&arr[0]) == &arr[1], ""); 312 static_assert(postdec(&arr[1]) == &arr[0], ""); 313 #if __cplusplus <= 202002L 314 static_assert(++ref(&arr[0]) == &arr[1], ""); 315 static_assert(++ref(&arr[9]) == &arr[10], ""); 316 static_assert(++ref(&arr[10]) == &arr[11], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} 317 static_assert(ref(&arr[0])++ == &arr[0], ""); 318 static_assert(ref(&arr[10])++ == &arr[10], ""); // expected-error {{constant}} expected-note {{cannot refer to element 11}} 319 static_assert(--ref(&arr[10]) == &arr[9], ""); 320 static_assert(--ref(&arr[1]) == &arr[0], ""); 321 static_assert(--ref(&arr[0]) != &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} 322 static_assert(ref(&arr[1])-- == &arr[1], ""); 323 static_assert(ref(&arr[0])-- == &arr[0], ""); // expected-error {{constant}} expected-note {{cannot refer to element -1}} 324 #endif 325 326 static_assert(postinc(0.0) == 1.0, ""); 327 static_assert(postdec(0.0) == -1.0, ""); 328 #if __cplusplus <= 202002L 329 int x; 330 static_assert(++ref(&x) == &x + 1, ""); 331 332 static_assert(++ref(0.0) == 1.0, ""); 333 static_assert(ref(0.0)++ == 0.0, ""); 334 static_assert(--ref(0.0) == -1.0, ""); 335 static_assert(ref(0.0)-- == 0.0, ""); 336 337 static_assert(++ref(1e100) == 1e100, ""); 338 static_assert(--ref(1e100) == 1e100, ""); 339 #endif 340 341 union U { 342 int a, b; 343 }; 344 constexpr int f(U u) { 345 return ++u.b; // expected-note {{increment of member 'b' of union with active member 'a'}} 346 } 347 constexpr int wrong_member = f({0}); // expected-error {{constant}} expected-note {{in call to 'f({.a = 0})'}} 348 constexpr int vol = --ref<volatile int>(0); // expected-error {{constant}} expected-note {{decrement of volatile-qualified}} 349 // cxx20_23-warning@-1 {{decrement of object of volatile-qualified type 'volatile int' is deprecated}} 350 351 constexpr int incr(int k) { 352 int x = k; 353 if (x++ == 100) 354 return x; 355 return incr(x); 356 } 357 static_assert(incr(0) == 101, ""); 358 } 359 360 namespace compound_assign { 361 constexpr bool test_int() { 362 int a = 3; 363 a += 6; 364 if (a != 9) return false; 365 a -= 2; 366 if (a != 7) return false; 367 a *= 3; 368 if (a != 21) return false; 369 if (&(a /= 10) != &a) return false; 370 if (a != 2) return false; 371 a <<= 3; 372 if (a != 16) return false; 373 a %= 6; 374 if (a != 4) return false; 375 a >>= 1; 376 if (a != 2) return false; 377 a ^= 10; 378 if (a != 8) return false; 379 a |= 5; 380 if (a != 13) return false; 381 a &= 14; 382 if (a != 12) return false; 383 a += -1.2; 384 if (a != 10) return false; 385 a -= 3.1; 386 if (a != 6) return false; 387 a *= 2.2; 388 if (a != 13) return false; 389 if (&(a /= 1.5) != &a) return false; 390 if (a != 8) return false; 391 return true; 392 } 393 static_assert(test_int(), ""); 394 395 constexpr bool test_float() { 396 float f = 123.; 397 f *= 2; 398 if (f != 246.) return false; 399 if ((f -= 0.5) != 245.5) return false; 400 if (f != 245.5) return false; 401 f /= 0.5; 402 if (f != 491.) return false; 403 f += -40; 404 if (f != 451.) return false; 405 return true; 406 } 407 static_assert(test_float(), ""); 408 409 constexpr bool test_bool() { 410 bool b = false; 411 b |= 2; 412 if (b != true) return false; 413 b <<= 1; 414 if (b != true) return false; 415 b *= 2; 416 if (b != true) return false; 417 b -= 1; 418 if (b != false) return false; 419 b -= 1; 420 if (b != true) return false; 421 b += -1; 422 if (b != false) return false; 423 b += 1; 424 if (b != true) return false; 425 b += 1; 426 if (b != true) return false; 427 b ^= b; 428 if (b != false) return false; 429 return true; 430 } 431 static_assert(test_bool(), ""); 432 433 constexpr bool test_ptr() { 434 int arr[123] = {}; 435 int *p = arr; 436 if ((p += 4) != &arr[4]) return false; 437 if (p != &arr[4]) return false; 438 p += -1; 439 if (p != &arr[3]) return false; 440 if ((p -= -10) != &arr[13]) return false; 441 if (p != &arr[13]) return false; 442 p -= 11; 443 if (p != &arr[2]) return false; 444 return true; 445 } 446 static_assert(test_ptr(), ""); 447 448 template<typename T> 449 constexpr bool test_overflow() { 450 T a = 1; 451 while (a != a / 2) 452 a *= 2; // expected-note {{value 2147483648 is outside the range}} expected-note {{ 9223372036854775808 }} 453 return true; 454 } 455 456 static_assert(test_overflow<int>(), ""); // expected-error {{constant}} expected-note {{call}} 457 static_assert(test_overflow<unsigned>(), ""); // ok, unsigned overflow is defined 458 static_assert(test_overflow<short>(), ""); // ok, short is promoted to int before multiplication 459 static_assert(test_overflow<unsigned short>(), ""); // ok 460 static_assert(test_overflow<unsigned long long>(), ""); // ok 461 static_assert(test_overflow<long long>(), ""); // expected-error {{constant}} expected-note {{call}} 462 static_assert(test_overflow<float>(), ""); // ok 463 static_assert(test_overflow<double>(), ""); // ok 464 465 constexpr short test_promotion(short k) { 466 short s = k; 467 s *= s; 468 return s; 469 } 470 static_assert(test_promotion(100) == 10000, ""); 471 static_assert(test_promotion(200) == -25536, ""); 472 static_assert(test_promotion(256) == 0, ""); 473 474 constexpr const char *test_bounds(const char *p, int o) { 475 return p += o; // expected-note {{element 5 of}} expected-note {{element -1 of}} expected-note {{element 1000 of}} 476 } 477 static_assert(test_bounds("foo", 0)[0] == 'f', ""); 478 static_assert(test_bounds("foo", 3)[0] == 0, ""); 479 static_assert(test_bounds("foo", 4)[-3] == 'o', ""); 480 static_assert(test_bounds(&"foo"[4], -4)[0] == 'f', ""); 481 static_assert(test_bounds("foo", 5) != 0, ""); // expected-error {{constant}} expected-note {{call}} 482 static_assert(test_bounds("foo", -1) != 0, ""); // expected-error {{constant}} expected-note {{call}} 483 static_assert(test_bounds("foo", 1000) != 0, ""); // expected-error {{constant}} expected-note {{call}} 484 } 485 486 namespace loops { 487 constexpr int fib_loop(int a) { 488 int f_k = 0, f_k_plus_one = 1; 489 for (int k = 1; k != a; ++k) { 490 int f_k_plus_two = f_k + f_k_plus_one; 491 f_k = f_k_plus_one; 492 f_k_plus_one = f_k_plus_two; 493 } 494 return f_k_plus_one; 495 } 496 static_assert(fib_loop(46) == 1836311903, ""); 497 498 constexpr bool breaks_work() { 499 int a = 0; 500 for (int n = 0; n != 100; ++n) { 501 ++a; 502 if (a == 5) continue; 503 if ((a % 5) == 0) break; 504 } 505 506 int b = 0; 507 while (b != 17) { 508 ++b; 509 if (b == 6) continue; 510 if ((b % 6) == 0) break; 511 } 512 513 int c = 0; 514 do { 515 ++c; 516 if (c == 7) continue; 517 if ((c % 7) == 0) break; 518 } while (c != 21); 519 520 return a == 10 && b == 12 && c == 14; 521 } 522 static_assert(breaks_work(), ""); 523 524 void not_constexpr(); 525 constexpr bool no_cont_after_break() { 526 for (;;) { 527 break; 528 not_constexpr(); 529 } 530 while (true) { 531 break; 532 not_constexpr(); 533 } 534 do { 535 break; 536 not_constexpr(); 537 } while (true); 538 return true; 539 } 540 static_assert(no_cont_after_break(), ""); 541 542 constexpr bool cond() { 543 for (int a = 1; bool b = a != 3; ++a) { 544 if (!b) 545 return false; 546 } 547 while (bool b = true) { 548 b = false; 549 break; 550 } 551 return true; 552 } 553 static_assert(cond(), ""); 554 555 constexpr int range_for() { 556 int arr[] = { 1, 2, 3, 4, 5 }; 557 int sum = 0; 558 for (int x : arr) 559 sum += x; 560 return sum; 561 } 562 static_assert(range_for() == 15, ""); 563 564 template<int...N> struct ints {}; 565 template<typename A, typename B> struct join_ints; 566 template<int...As, int...Bs> struct join_ints<ints<As...>, ints<Bs...>> { 567 using type = ints<As..., sizeof...(As) + Bs...>; 568 }; 569 template<unsigned N> struct make_ints { 570 using type = typename join_ints<typename make_ints<N/2>::type, typename make_ints<(N+1)/2>::type>::type; 571 }; 572 template<> struct make_ints<0> { using type = ints<>; }; 573 template<> struct make_ints<1> { using type = ints<0>; }; 574 575 struct ignore { template<typename ...Ts> constexpr ignore(Ts &&...) {} }; 576 577 template<typename T, unsigned N> struct array { 578 constexpr array() : arr{} {} 579 template<typename ...X> 580 constexpr array(X ...x) : arr{} { 581 init(typename make_ints<sizeof...(X)>::type{}, x...); 582 } 583 template<int ...I, typename ...X> constexpr void init(ints<I...>, X ...x) { 584 ignore{arr[I] = x ...}; 585 } 586 T arr[N]; 587 struct iterator { 588 T *p; 589 constexpr explicit iterator(T *p) : p(p) {} 590 constexpr bool operator!=(iterator o) { return p != o.p; } 591 constexpr iterator &operator++() { ++p; return *this; } 592 constexpr T &operator*() { return *p; } 593 }; 594 constexpr iterator begin() { return iterator(arr); } 595 constexpr iterator end() { return iterator(arr + N); } 596 }; 597 598 constexpr int range_for_2() { 599 array<int, 5> arr { 1, 2, 3, 4, 5 }; 600 int sum = 0; 601 for (int k : arr) { 602 sum += k; 603 if (sum > 8) break; 604 } 605 return sum; 606 } 607 static_assert(range_for_2() == 10, ""); 608 } 609 610 namespace assignment_op { 611 struct A { 612 constexpr A() : n(5) {} 613 int n; 614 struct B { 615 int k = 1; 616 union U { 617 constexpr U() : y(4) {} 618 int x; 619 int y; 620 } u; 621 } b; 622 }; 623 constexpr bool testA() { 624 A a, b; 625 a.n = 7; 626 a.b.u.y = 5; 627 b = a; 628 return b.n == 7 && b.b.u.y == 5 && b.b.k == 1; 629 } 630 static_assert(testA(), ""); 631 632 struct B { 633 bool assigned = false; 634 constexpr B &operator=(const B&) { 635 assigned = true; 636 return *this; 637 } 638 }; 639 struct C : B { 640 B b; 641 int n = 5; 642 }; 643 constexpr bool testC() { 644 C c, d; 645 c.n = 7; 646 d = c; 647 c.n = 3; 648 return d.n == 7 && d.assigned && d.b.assigned; 649 } 650 static_assert(testC(), ""); 651 } 652 653 namespace switch_stmt { 654 constexpr bool no_such_case(int n) { 655 switch (n) { case 1: return false; } 656 return true; 657 } 658 static_assert(no_such_case(0), ""); 659 660 constexpr int f(char k) { 661 bool b = false; 662 int z = 6; 663 switch (k) { 664 return -1; 665 case 0: 666 if (false) { 667 case 1: 668 z = 1; 669 for (; b;) { 670 return 5; 671 while (0) 672 case 2: return 2; 673 case 7: z = 7; 674 do case 6: { 675 return z; 676 if (false) 677 case 3: return 3; 678 case 4: z = 4; 679 } while (1); 680 case 5: b = true; 681 case 9: z = 9; 682 } 683 return z; 684 } else if (false) case 8: z = 8; 685 else if (false) { 686 case 10: 687 z = -10; 688 break; 689 } 690 else z = 0; 691 return z; 692 default: 693 return -1; 694 } 695 return -z; 696 } 697 static_assert(f(0) == 0, ""); 698 static_assert(f(1) == 1, ""); 699 static_assert(f(2) == 2, ""); 700 static_assert(f(3) == 3, ""); 701 static_assert(f(4) == 4, ""); 702 static_assert(f(5) == 5, ""); 703 static_assert(f(6) == 6, ""); 704 static_assert(f(7) == 7, ""); 705 static_assert(f(8) == 8, ""); 706 static_assert(f(9) == 9, ""); 707 static_assert(f(10) == 10, ""); 708 709 // Check that we can continue an outer loop from within a switch. 710 constexpr bool contin() { 711 for (int n = 0; n != 10; ++n) { 712 switch (n) { 713 case 0: 714 ++n; 715 continue; 716 case 1: 717 return false; 718 case 2: 719 return true; 720 } 721 } 722 return false; 723 } 724 static_assert(contin(), ""); 725 726 constexpr bool switch_into_for() { 727 int n = 0; 728 switch (n) { 729 for (; n == 1; ++n) { 730 return n == 1; 731 case 0: ; 732 } 733 } 734 return false; 735 } 736 static_assert(switch_into_for(), ""); 737 738 constexpr void duff_copy(char *a, const char *b, int n) { 739 switch ((n - 1) % 8 + 1) { 740 for ( ; n; n = (n - 1) & ~7) { 741 case 8: a[n-8] = b[n-8]; 742 case 7: a[n-7] = b[n-7]; 743 case 6: a[n-6] = b[n-6]; 744 case 5: a[n-5] = b[n-5]; 745 case 4: a[n-4] = b[n-4]; 746 case 3: a[n-3] = b[n-3]; 747 case 2: a[n-2] = b[n-2]; 748 case 1: a[n-1] = b[n-1]; 749 } 750 case 0: ; 751 } 752 } 753 754 constexpr bool test_copy(const char *str, int n) { 755 char buffer[16] = {}; 756 duff_copy(buffer, str, n); 757 for (int i = 0; i != sizeof(buffer); ++i) 758 if (buffer[i] != (i < n ? str[i] : 0)) 759 return false; 760 return true; 761 } 762 static_assert(test_copy("foo", 0), ""); 763 static_assert(test_copy("foo", 1), ""); 764 static_assert(test_copy("foo", 2), ""); 765 static_assert(test_copy("hello world", 0), ""); 766 static_assert(test_copy("hello world", 7), ""); 767 static_assert(test_copy("hello world", 8), ""); 768 static_assert(test_copy("hello world", 9), ""); 769 static_assert(test_copy("hello world", 10), ""); 770 static_assert(test_copy("hello world", 10), ""); 771 } 772 773 namespace deduced_return_type { 774 constexpr auto f() { return 0; } 775 template<typename T> constexpr auto g(T t) { return t; } 776 static_assert(f() == 0, ""); 777 static_assert(g(true), ""); 778 } 779 780 namespace modify_temporary_during_construction { 781 struct A { int &&temporary; int x; int y; }; 782 constexpr int f(int &r) { r *= 9; return r - 12; } 783 constexpr A a = { 6, f(a.temporary), a.temporary }; // expected-note {{temporary created here}} 784 static_assert(a.x == 42, ""); 785 static_assert(a.y == 54, ""); 786 constexpr int k = a.temporary++; // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}} 787 } 788 789 namespace std { 790 typedef decltype(sizeof(int)) size_t; 791 792 template <class _E> 793 class initializer_list 794 { 795 const _E* __begin_; 796 size_t __size_; 797 798 constexpr initializer_list(const _E* __b, size_t __s) 799 : __begin_(__b), 800 __size_(__s) 801 {} 802 803 public: 804 typedef _E value_type; 805 typedef const _E& reference; 806 typedef const _E& const_reference; 807 typedef size_t size_type; 808 809 typedef const _E* iterator; 810 typedef const _E* const_iterator; 811 812 constexpr initializer_list() : __begin_(nullptr), __size_(0) {} 813 814 constexpr size_t size() const {return __size_;} 815 constexpr const _E* begin() const {return __begin_;} 816 constexpr const _E* end() const {return __begin_ + __size_;} 817 }; 818 } 819 820 namespace InitializerList { 821 constexpr int sum(std::initializer_list<int> ints) { 822 int total = 0; 823 for (int n : ints) total += n; 824 return total; 825 } 826 static_assert(sum({1, 2, 3, 4, 5}) == 15, ""); 827 } 828 829 namespace StmtExpr { 830 constexpr int f(int k) { 831 switch (k) { 832 case 0: 833 return 0; 834 835 ({ // expected-note {{jump enters a statement expression}} 836 case 1:// expected-error {{cannot jump from switch statement to this case label}} \ 837 // expected-note {{not supported}} 838 return 1; 839 }); 840 } 841 } 842 static_assert(f(1) == 1, ""); // expected-error {{constant expression}} expected-note {{in call}} 843 844 constexpr int g() { 845 return ({ int n; n; }); // expected-note {{read of uninitialized object}} 846 } 847 static_assert(g() == 0, ""); // expected-error {{constant expression}} expected-note {{in call}} 848 849 // FIXME: We should handle the void statement expression case. 850 constexpr int h() { // cxx14_20-error {{never produces a constant}} 851 ({ if (true) {} }); // cxx14_20-note {{not supported}} 852 return 0; 853 } 854 } 855 856 namespace VirtualFromBase { 857 struct S1 { 858 virtual int f() const; 859 }; 860 struct S2 { 861 virtual int f(); 862 }; 863 template <typename T> struct X : T { 864 constexpr X() {} 865 double d = 0.0; 866 constexpr int f() { return sizeof(T); } 867 }; 868 869 // Non-virtual f(), OK. 870 constexpr X<X<S1>> xxs1; 871 constexpr X<S1> *p = const_cast<X<X<S1>>*>(&xxs1); 872 static_assert(p->f() == sizeof(S1), ""); 873 874 // Virtual f(), not OK. 875 constexpr X<X<S2>> xxs2; 876 constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2); 877 static_assert(q->f() == sizeof(X<S2>), ""); // cxx14-error {{constant expression}} cxx14-note {{virtual function}} 878 } 879 880 namespace Lifetime { 881 constexpr int &get(int &&r) { return r; } 882 // cxx23-error@-1 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} 883 constexpr int f() { 884 int &r = get(123); 885 return r; 886 // cxx14_20-note@-1 {{read of object outside its lifetime}} 887 } 888 static_assert(f() == 123, ""); // expected-error {{constant expression}} cxx14_20-note {{in call}} 889 890 constexpr int g() { 891 int *p = 0; 892 { 893 int n = 0; 894 p = &n; 895 n = 42; 896 } 897 *p = 123; // expected-note {{assignment to object outside its lifetime}} 898 return *p; 899 } 900 static_assert(g() == 42, ""); // expected-error {{constant expression}} expected-note {{in call}} 901 902 constexpr int h(int n) { 903 int *p[4] = {}; 904 int &&r = 1; 905 p[0] = &r; 906 while (int a = 1) { 907 p[1] = &a; 908 for (int b = 1; int c = 1; ) { 909 p[2] = &b, p[3] = &c; 910 break; 911 } 912 break; 913 } 914 *p[n] = 0; // expected-note 3{{assignment to object outside its lifetime}} 915 return *p[n]; 916 } 917 static_assert(h(0) == 0, ""); // ok, lifetime-extended 918 static_assert(h(1) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}} 919 static_assert(h(2) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}} 920 static_assert(h(3) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}} 921 922 constexpr void lifetime_versus_loops() { 923 int *p = 0; 924 for (int i = 0; i != 2; ++i) { 925 int *q = p; 926 int n = 0; 927 p = &n; 928 if (i) 929 // This modifies the 'n' from the previous iteration of the loop outside 930 // its lifetime. 931 ++*q; // expected-note {{increment of object outside its lifetime}} 932 } 933 } 934 static_assert((lifetime_versus_loops(), true), ""); // expected-error {{constant expression}} expected-note {{in call}} 935 } 936 937 namespace Bitfields { 938 struct A { 939 bool b : 1; 940 int n : 4; 941 unsigned u : 5; 942 }; 943 constexpr bool test() { 944 A a {}; 945 a.b += 2; 946 --a.n; 947 --a.u; 948 a.n = -a.n * 3; 949 return a.b == true && a.n == 3 && a.u == 31; 950 } 951 static_assert(test(), ""); 952 } 953 954 namespace PR17615 { 955 struct A { 956 int &&r; 957 constexpr A(int &&r) : r(static_cast<int &&>(r)) {} 958 constexpr A() : A(0) { 959 (void)+r; // expected-note {{outside its lifetime}} 960 } 961 }; 962 constexpr int k = A().r; // expected-error {{constant expression}} expected-note {{in call to}} 963 } 964 965 namespace PR17331 { 966 template<typename T, unsigned int N> 967 constexpr T sum(const T (&arr)[N]) { 968 T result = 0; 969 for (T i : arr) 970 result += i; 971 return result; 972 } 973 974 constexpr int ARR[] = { 1, 2, 3, 4, 5 }; 975 static_assert(sum(ARR) == 15, ""); 976 } 977 978 namespace EmptyClass { 979 struct E1 {} e1; 980 union E2 {} e2; // expected-note 4{{here}} 981 struct E3 : E1 {} e3; 982 983 template<typename E> 984 constexpr int f(E &a, int kind) { 985 switch (kind) { 986 case 0: { E e(a); return 0; } // expected-note {{read}} expected-note {{in call}} 987 case 1: { E e(static_cast<E&&>(a)); return 0; } // expected-note {{read}} expected-note {{in call}} 988 case 2: { E e; e = a; return 0; } // expected-note {{read}} expected-note {{in call}} 989 case 3: { E e; e = static_cast<E&&>(a); return 0; } // expected-note {{read}} expected-note {{in call}} 990 } 991 } 992 constexpr int test1 = f(e1, 0); 993 constexpr int test2 = f(e2, 0); // expected-error {{constant expression}} expected-note {{in call}} 994 constexpr int test3 = f(e3, 0); 995 constexpr int test4 = f(e1, 1); 996 constexpr int test5 = f(e2, 1); // expected-error {{constant expression}} expected-note {{in call}} 997 constexpr int test6 = f(e3, 1); 998 constexpr int test7 = f(e1, 2); 999 constexpr int test8 = f(e2, 2); // expected-error {{constant expression}} expected-note {{in call}} 1000 constexpr int test9 = f(e3, 2); 1001 constexpr int testa = f(e1, 3); 1002 constexpr int testb = f(e2, 3); // expected-error {{constant expression}} expected-note {{in call}} 1003 constexpr int testc = f(e3, 3); 1004 } 1005 1006 namespace SpeculativeEvalWrites { 1007 // Ensure that we don't try to speculatively evaluate writes. 1008 constexpr int f() { 1009 int i = 0; 1010 int a = 0; 1011 // __builtin_object_size speculatively evaluates its first argument. 1012 __builtin_object_size((i = 1, &a), 0); 1013 return i; 1014 } 1015 1016 static_assert(!f(), ""); 1017 } 1018 1019 namespace PR27989 { 1020 constexpr int f(int n) { 1021 int a = (n = 1, 0); 1022 return n; 1023 } 1024 static_assert(f(0) == 1, ""); 1025 } 1026 1027 namespace const_char { 1028 template <int N> 1029 constexpr int sum(const char (&Arr)[N]) { 1030 int S = 0; 1031 for (unsigned I = 0; I != N; ++I) 1032 S += Arr[I]; // expected-note 2{{read of non-constexpr variable 'Cs' is not allowed}} 1033 return S; 1034 } 1035 1036 // As an extension, we support evaluating some things that are `const` as though 1037 // they were `constexpr` when folding, but it should not be allowed in normal 1038 // constexpr evaluation. 1039 const char Cs[] = {'a', 'b'}; // expected-note 2{{declared here}} 1040 void foo() __attribute__((enable_if(sum(Cs) == 'a' + 'b', ""))); 1041 void run() { foo(); } 1042 1043 static_assert(sum(Cs) == 'a' + 'b', ""); // expected-error{{not an integral constant expression}} expected-note{{in call to 'sum<2>(Cs)'}} 1044 constexpr int S = sum(Cs); // expected-error{{must be initialized by a constant expression}} expected-note{{in call}} 1045 } 1046 1047 constexpr void PR28739(int n) { // cxx14_20-error {{never produces a constant}} 1048 int *p = &n; // expected-note {{array 'p' declared here}} 1049 p += (__int128)(unsigned long)-1; // cxx14_20-note {{cannot refer to element 18446744073709551615 of non-array object in a constant expression}} 1050 // expected-warning@-1 {{the pointer incremented by 18446744073709551615 refers past the last possible element for an array in 64-bit address space containing 32-bit (4-byte) elements (max possible 4611686018427387904 elements)}} 1051 } 1052 1053 constexpr void Void(int n) { 1054 void(n + 1); 1055 void(); 1056 } 1057 constexpr int void_test = (Void(0), 1); 1058 1059 namespace PR19741 { 1060 constexpr void addone(int &m) { m++; } 1061 1062 struct S { 1063 int m = 0; 1064 constexpr S() { addone(m); } 1065 }; 1066 constexpr bool evalS() { 1067 constexpr S s; 1068 return s.m == 1; 1069 } 1070 static_assert(evalS(), ""); 1071 1072 struct Nested { 1073 struct First { int x = 42; }; 1074 union { 1075 First first; 1076 int second; 1077 }; 1078 int x; 1079 constexpr Nested(int x) : first(), x(x) { x = 4; } 1080 constexpr Nested() : Nested(42) { 1081 addone(first.x); 1082 x = 3; 1083 } 1084 }; 1085 constexpr bool evalNested() { 1086 constexpr Nested N; 1087 return N.first.x == 43; 1088 } 1089 static_assert(evalNested(), ""); 1090 } // namespace PR19741 1091 1092 namespace Mutable { 1093 struct A { mutable int n; }; // expected-note 2{{here}} 1094 constexpr int k = A{123}.n; // ok 1095 static_assert(k == 123, ""); 1096 1097 struct Q { A &&a; int b = a.n; }; 1098 constexpr Q q = { A{456} }; // expected-note {{temporary}} 1099 static_assert(q.b == 456, ""); 1100 static_assert(q.a.n == 456, ""); // expected-error {{constant expression}} expected-note {{outside the expression that created the temporary}} 1101 1102 constexpr A a = {123}; 1103 constexpr int m = a.n; // expected-error {{constant expression}} expected-note {{mutable}} 1104 1105 constexpr Q r = { static_cast<A&&>(const_cast<A&>(a)) }; // expected-error {{constant expression}} expected-note@-8 {{mutable}} 1106 1107 struct B { 1108 mutable int n; // expected-note {{here}} 1109 int m; 1110 constexpr B() : n(1), m(n) {} // ok 1111 }; 1112 constexpr B b; 1113 constexpr int p = b.n; // expected-error {{constant expression}} expected-note {{mutable}} 1114 } 1115 1116 namespace IndirectFields { 1117 1118 // Reference indirect field. 1119 struct A { 1120 struct { 1121 union { 1122 int x = x = 3; // cxx14-note {{outside its lifetime}} 1123 }; 1124 }; 1125 constexpr A() {} 1126 }; 1127 static_assert(A().x == 3, ""); // cxx14-error{{not an integral constant expression}} cxx14-note{{in call to 'A()'}} 1128 1129 // Reference another indirect field, with different 'this'. 1130 struct B { 1131 struct { 1132 union { 1133 int x = 3; 1134 }; 1135 int y = x; 1136 }; 1137 constexpr B() {} 1138 }; 1139 static_assert(B().y == 3, ""); 1140 1141 // Nested evaluation of indirect field initializers. 1142 struct C { 1143 union { 1144 int x = 1; 1145 }; 1146 }; 1147 struct D { 1148 struct { 1149 C c; 1150 int y = c.x + 1; 1151 }; 1152 }; 1153 static_assert(D().y == 2, ""); 1154 1155 // Explicit 'this'. 1156 struct E { 1157 int n = 0; 1158 struct { 1159 void *x = this; 1160 }; 1161 void *y = this; 1162 }; 1163 constexpr E e1 = E(); 1164 static_assert(e1.x != e1.y, ""); 1165 constexpr E e2 = E{0}; 1166 static_assert(e2.x != e2.y, ""); 1167 1168 } // namespace IndirectFields 1169 1170 constexpr bool indirect_builtin_constant_p(const char *__s) { 1171 return __builtin_constant_p(*__s); 1172 } 1173 constexpr bool n = indirect_builtin_constant_p("a"); 1174 1175 __attribute__((enable_if(indirect_builtin_constant_p("a") == n, "OK"))) 1176 int test_in_enable_if() { return 0; } 1177 int n2 = test_in_enable_if(); 1178 1179 template <bool n = indirect_builtin_constant_p("a")> 1180 int test_in_template_param() { return 0; } 1181 int n3 = test_in_template_param(); 1182 1183 void test_in_case(int n) { 1184 switch (n) { 1185 case indirect_builtin_constant_p("abc"): 1186 break; 1187 } 1188 } 1189 enum InEnum1 { 1190 ONE = indirect_builtin_constant_p("abc") 1191 }; 1192 enum InEnum2 : int { 1193 TWO = indirect_builtin_constant_p("abc") 1194 }; 1195 enum class InEnum3 { 1196 THREE = indirect_builtin_constant_p("abc") 1197 }; 1198 1199 // [class.ctor]p4: 1200 // A constructor can be invoked for a const, volatile or const volatile 1201 // object. const and volatile semantics are not applied on an object under 1202 // construction. They come into effect when the constructor for the most 1203 // derived object ends. 1204 namespace ObjectsUnderConstruction { 1205 struct A { 1206 int n; 1207 constexpr A() : n(1) { n = 2; } 1208 }; 1209 struct B { 1210 const A a; 1211 constexpr B(bool mutate) { 1212 if (mutate) 1213 const_cast<A &>(a).n = 3; // expected-note {{modification of object of const-qualified type 'const int'}} 1214 } 1215 }; 1216 constexpr B b(false); 1217 static_assert(b.a.n == 2, ""); 1218 constexpr B bad(true); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'B(true)'}} 1219 1220 struct C { 1221 int n; 1222 constexpr C() : n(1) { n = 2; } 1223 }; 1224 constexpr int f(bool get) { 1225 volatile C c; // expected-note {{here}} 1226 return get ? const_cast<int&>(c.n) : 0; // expected-note {{read of volatile object 'c'}} 1227 } 1228 static_assert(f(false) == 0, ""); // ok, can modify volatile c.n during c's initialization: it's not volatile then 1229 static_assert(f(true) == 2, ""); // expected-error {{constant}} expected-note {{in call}} 1230 1231 struct Aggregate { 1232 int x = 0; 1233 int y = ++x; 1234 }; 1235 constexpr Aggregate aggr1; 1236 static_assert(aggr1.x == 1 && aggr1.y == 1, ""); 1237 // FIXME: This is not specified by the standard, but sanity requires it. 1238 constexpr Aggregate aggr2 = {}; 1239 static_assert(aggr2.x == 1 && aggr2.y == 1, ""); 1240 1241 // The lifetime of 'n' begins at the initialization, not before. 1242 constexpr int n = ++const_cast<int&>(n); // expected-error {{constant expression}} expected-note {{increment of object outside its lifetime}} 1243 } 1244 1245 namespace PR39728 { 1246 struct Comment0 { 1247 Comment0 &operator=(const Comment0 &) = default; 1248 ~Comment0() = default; 1249 }; 1250 constexpr void f() { 1251 Comment0 a; 1252 a = a; 1253 } 1254 static_assert((f(), true), ""); 1255 struct Comment1 { 1256 constexpr Comment1 &operator=(const Comment1 &) = default; // OK 1257 ~Comment1() = default; 1258 }; 1259 } 1260 1261 namespace TemporaryWithBadPointer { 1262 constexpr int *get_bad_pointer() { 1263 int n = 0; // expected-note 2{{here}} 1264 return &n; // expected-warning {{stack}} 1265 } 1266 constexpr int *bad_pointer = get_bad_pointer(); // expected-error {{constant expression}} expected-note {{pointer to 'n' is not a constant expression}} 1267 1268 struct DoBadThings { int *&℘ int n; }; 1269 constexpr DoBadThings dbt = { // expected-error {{constant expression}} 1270 nullptr, // expected-note {{pointer to 'n' is not a constant expression}} 1271 (dbt.wp = get_bad_pointer(), 0) 1272 }; 1273 1274 constexpr DoBadThings dbt2 = { // ok 1275 get_bad_pointer(), 1276 (dbt2.wp = nullptr, 0) 1277 }; 1278 } 1279 1280 namespace UninitCompoundAssign { 1281 constexpr int scalar(int a) { 1282 int sum; // cxx14-warning {{uninitialized variable in a constexpr function is a C++20 extension}} 1283 sum += a; // expected-note {{read of uninitialized object}}; 1284 return 0; 1285 } 1286 static_assert(scalar(3), ""); // expected-error {{constant expression}} \ 1287 // expected-note {{in call to 'scalar(3)'}} 1288 1289 constexpr int array(int a) { 1290 int arr[3]; // cxx14-warning {{uninitialized variable in a constexpr function is a C++20 extension}} 1291 arr[1] += a; // expected-note {{read of uninitialized object}}; 1292 return 0; 1293 } 1294 static_assert(array(3), ""); // expected-error {{constant expression}} \ 1295 // expected-note {{in call to 'array(3)'}} 1296 1297 struct Foo { 1298 int val; // cxx14-note{{member not initialized by constructor}} 1299 constexpr Foo() {} // cxx14-warning {{constexpr constructor that does not initialize all members is a C++20 extension}} 1300 }; 1301 constexpr int field(int a) { 1302 Foo f; 1303 f.val += a; // expected-note {{read of uninitialized object}}; 1304 return 0; 1305 } 1306 static_assert(field(3), ""); // expected-error {{constant expression}} \ 1307 // expected-note {{in call to 'field(3)'}} 1308 } 1309 1310 namespace literal_comparison { 1311 1312 constexpr bool different_in_loop(bool b = false) { 1313 if (b) return false; 1314 1315 const char *p[2] = {}; 1316 for (const char *&r : p) 1317 r = "hello"; 1318 return p[0] == p[1]; // expected-note {{addresses of potentially overlapping literals}} 1319 } 1320 constexpr bool check = different_in_loop(); 1321 // expected-error@-1 {{}} expected-note@-1 {{in call}} 1322 1323 } 1324