1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s 2 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify=expected,both %s 3 // RUN: %clang_cc1 -verify=ref,both %s 4 // RUN: %clang_cc1 -verify=ref,both -std=c++20 %s 5 6 constexpr int m = 3; 7 constexpr const int *foo[][5] = { 8 {nullptr, &m, nullptr, nullptr, nullptr}, 9 {nullptr, nullptr, &m, nullptr, nullptr}, 10 {nullptr, nullptr, nullptr, &m, nullptr}, 11 }; 12 13 static_assert(foo[0][0] == nullptr, ""); 14 static_assert(foo[0][1] == &m, ""); 15 static_assert(foo[0][2] == nullptr, ""); 16 static_assert(foo[0][3] == nullptr, ""); 17 static_assert(foo[0][4] == nullptr, ""); 18 static_assert(foo[1][0] == nullptr, ""); 19 static_assert(foo[1][1] == nullptr, ""); 20 static_assert(foo[1][2] == &m, ""); 21 static_assert(foo[1][3] == nullptr, ""); 22 static_assert(foo[1][4] == nullptr, ""); 23 static_assert(foo[2][0] == nullptr, ""); 24 static_assert(foo[2][1] == nullptr, ""); 25 static_assert(foo[2][2] == nullptr, ""); 26 static_assert(foo[2][3] == &m, ""); 27 static_assert(foo[2][4] == nullptr, ""); 28 29 constexpr int afterEnd[] = {1,2,3}; 30 static_assert(&afterEnd[3] == afterEnd + 3, ""); 31 32 constexpr int ZeroSizeArray[] = {}; 33 34 constexpr int SomeInt[] = {1}; 35 constexpr int getSomeInt() { return *SomeInt; } 36 static_assert(getSomeInt() == 1, ""); 37 38 /// A init list for a primitive value. 39 constexpr int f{5}; 40 static_assert(f == 5, ""); 41 42 43 constexpr int getElement(int i) { 44 int values[] = {1, 4, 9, 16, 25, 36}; 45 return values[i]; 46 } 47 static_assert(getElement(1) == 4, ""); 48 static_assert(getElement(5) == 36, ""); 49 50 constexpr int data[] = {5, 4, 3, 2, 1}; 51 constexpr int getElement(const int *Arr, int index) { 52 return *(Arr + index); 53 } 54 55 constexpr int derefPtr(const int *d) { 56 return *d; 57 } 58 static_assert(derefPtr(data) == 5, ""); 59 60 /// Make sure we can refer to the one-past-the-end element 61 /// and then return back to the end of the array. 62 static_assert((&data[5])[-1] == 1, ""); 63 64 constexpr int storePtr() { 65 int b[] = {1,2,3,4}; 66 int *c = b; 67 68 *c = 4; 69 return *c; 70 } 71 static_assert(storePtr() == 4, ""); 72 73 74 static_assert(getElement(data, 1) == 4, ""); 75 static_assert(getElement(data, 4) == 1, ""); 76 77 constexpr int getElementFromEnd(const int *Arr, int size, int index) { 78 return *(Arr + size - index - 1); 79 } 80 static_assert(getElementFromEnd(data, 5, 0) == 1, ""); 81 static_assert(getElementFromEnd(data, 5, 4) == 5, ""); 82 83 constexpr int getFirstElem(const int *a) { 84 return a[0]; // both-note {{read of dereferenced null pointer}} 85 } 86 static_assert(getFirstElem(nullptr) == 1, ""); // both-error {{not an integral constant expression}} \ 87 // both-note {{in call to}} 88 89 constexpr static int arr[2] = {1,2}; 90 constexpr static int arr2[2] = {3,4}; 91 constexpr int *p1 = nullptr; 92 constexpr int *p2 = p1 + 1; // both-error {{must be initialized by a constant expression}} \ 93 // both-note {{cannot perform pointer arithmetic on null pointer}} 94 constexpr int *p3 = p1 + 0; 95 constexpr int *p4 = p1 - 0; 96 constexpr int *p5 = 0 + p1; 97 constexpr int *p6 = 0 - p1; // both-error {{invalid operands to binary expression}} 98 99 constexpr int const * ap1 = &arr[0]; 100 constexpr int const * ap2 = ap1 + 3; // both-error {{must be initialized by a constant expression}} \ 101 // both-note {{cannot refer to element 3 of array of 2}} 102 103 constexpr auto ap3 = arr - 1; // both-error {{must be initialized by a constant expression}} \ 104 // both-note {{cannot refer to element -1}} 105 constexpr int k1 = &arr[1] - &arr[0]; 106 static_assert(k1 == 1, ""); 107 static_assert((&arr[0] - &arr[1]) == -1, ""); 108 109 constexpr int k2 = &arr2[1] - &arr[0]; // both-error {{must be initialized by a constant expression}} 110 111 static_assert((arr + 0) == arr, ""); 112 static_assert(&arr[0] == arr, ""); 113 static_assert(*(&arr[0]) == 1, ""); 114 static_assert(*(&arr[1]) == 2, ""); 115 116 constexpr const int *OOB = (arr + 3) - 3; // both-error {{must be initialized by a constant expression}} \ 117 // both-note {{cannot refer to element 3 of array of 2 elements}} 118 119 template<typename T> 120 constexpr T getElementOf(T* array, int i) { 121 return array[i]; 122 } 123 static_assert(getElementOf(foo[0], 1) == &m, ""); 124 125 126 template <typename T, int N> 127 constexpr T& getElementOfArray(T (&array)[N], int I) { 128 return array[I]; 129 } 130 static_assert(getElementOfArray(foo[2], 3) == &m, ""); 131 132 133 static_assert(data[0] == 4, ""); // both-error{{failed}} \ 134 // both-note{{5 == 4}} 135 136 constexpr int dynamic[] = { 137 f, 3, 2 + 5, data[3], *getElementOf(foo[2], 3) 138 }; 139 static_assert(dynamic[0] == f, ""); 140 static_assert(dynamic[3] == 2, ""); 141 142 143 constexpr int dependent[4] = { 144 0, 1, dependent[0], dependent[1] 145 }; 146 static_assert(dependent[2] == dependent[0], ""); 147 static_assert(dependent[3] == dependent[1], ""); 148 149 union { char x[]; } r = {0}; 150 151 #pragma clang diagnostic push 152 #pragma clang diagnostic ignored "-Wc99-extensions" 153 #pragma clang diagnostic ignored "-Winitializer-overrides" 154 constexpr int DI[] = { 155 [0] = 10, 156 [1] = 20, 157 30, 158 40, 159 [1] = 50 160 }; 161 static_assert(DI[0] == 10, ""); 162 static_assert(DI[1] == 50, ""); 163 static_assert(DI[2] == 30, ""); 164 static_assert(DI[3] == 40, ""); 165 166 constexpr int addThreeElements(const int v[3]) { 167 return v[0] + v[1] + v[2]; 168 } 169 constexpr int is[] = {10, 20, 30 }; 170 static_assert(addThreeElements(is) == 60, ""); 171 172 struct fred { 173 char s [6]; 174 int n; 175 }; 176 177 struct fred y [] = { [0] = { .s[0] = 'q' } }; 178 #pragma clang diagnostic pop 179 180 namespace indices { 181 constexpr int first[] = {1}; 182 constexpr int firstValue = first[2]; // both-error {{must be initialized by a constant expression}} \ 183 // both-note {{cannot refer to element 2 of array of 1}} 184 185 constexpr int second[10] = {17}; 186 constexpr int secondValue = second[10];// both-error {{must be initialized by a constant expression}} \ 187 // both-note {{read of dereferenced one-past-the-end pointer}} \ 188 189 constexpr int negative = second[-2]; // both-error {{must be initialized by a constant expression}} \ 190 // both-note {{cannot refer to element -2 of array of 10}} 191 }; 192 193 namespace DefaultInit { 194 template <typename T, unsigned N> 195 struct B { 196 T a[N]; 197 }; 198 199 int f() { 200 constexpr B<int,10> arr = {}; 201 constexpr int x = arr.a[0]; 202 } 203 }; 204 205 class A { 206 public: 207 int a; 208 constexpr A(int m = 2) : a(10 + m) {} 209 }; 210 class AU { 211 public: 212 int a; 213 constexpr AU() : a(5 / 0) {} // both-warning {{division by zero is undefined}} \ 214 // both-note 2{{division by zero}} \ 215 // both-error {{never produces a constant expression}} 216 }; 217 class B { 218 public: 219 A a[2]; 220 constexpr B() {} 221 }; 222 constexpr B b; 223 static_assert(b.a[0].a == 12, ""); 224 static_assert(b.a[1].a == 12, ""); 225 226 class BU { 227 public: 228 AU a[2]; 229 constexpr BU() {} // both-note {{in call to 'AU()'}} 230 }; 231 constexpr BU bu; // both-error {{must be initialized by a constant expression}} \ 232 // both-note {{in call to 'BU()'}} 233 234 namespace IncDec { 235 constexpr int getNextElem(const int *A, int I) { 236 const int *B = (A + I); 237 ++B; 238 return *B; 239 } 240 constexpr int E[] = {1,2,3,4}; 241 242 static_assert(getNextElem(E, 1) == 3, ""); 243 244 constexpr int getFirst() { 245 const int *e = E; 246 return *(e++); 247 } 248 static_assert(getFirst() == 1, ""); 249 250 constexpr int getFirst2() { 251 const int *e = E; 252 e++; 253 return *e; 254 } 255 static_assert(getFirst2() == 2, ""); 256 257 constexpr int getSecond() { 258 const int *e = E; 259 return *(++e); 260 } 261 static_assert(getSecond() == 2, ""); 262 263 constexpr int getSecond2() { 264 const int *e = E; 265 ++e; 266 return *e; 267 } 268 static_assert(getSecond2() == 2, ""); 269 270 constexpr int getLast() { 271 const int *e = E + 3; 272 return *(e--); 273 } 274 static_assert(getLast() == 4, ""); 275 276 constexpr int getLast2() { 277 const int *e = E + 3; 278 e--; 279 return *e; 280 } 281 static_assert(getLast2() == 3, ""); 282 283 constexpr int getSecondToLast() { 284 const int *e = E + 3; 285 return *(--e); 286 } 287 static_assert(getSecondToLast() == 3, ""); 288 289 constexpr int getSecondToLast2() { 290 const int *e = E + 3; 291 --e; 292 return *e; 293 } 294 static_assert(getSecondToLast2() == 3, ""); 295 296 constexpr int bad1() { // both-error {{never produces a constant expression}} 297 const int *e = E + 3; 298 e++; // This is fine because it's a one-past-the-end pointer 299 return *e; // both-note 2{{read of dereferenced one-past-the-end pointer}} 300 } 301 static_assert(bad1() == 0, ""); // both-error {{not an integral constant expression}} \ 302 // both-note {{in call to}} 303 304 constexpr int bad2() { // both-error {{never produces a constant expression}} 305 const int *e = E + 4; 306 e++; // both-note 2{{cannot refer to element 5 of array of 4 elements}} 307 return *e; // This is UB as well 308 } 309 static_assert(bad2() == 0, ""); // both-error {{not an integral constant expression}} \ 310 // both-note {{in call to}} 311 312 constexpr int bad3() { // both-error {{never produces a constant expression}} 313 const int *e = E; 314 e--; // both-note 2{{cannot refer to element -1 of array of 4 elements}} 315 return *e; // This is UB as well 316 } 317 static_assert(bad3() == 0, ""); // both-error {{not an integral constant expression}} \ 318 // both-note {{in call to}} 319 320 constexpr int nullptr1(bool Pre) { 321 int *a = nullptr; 322 if (Pre) 323 ++a; // both-note {{arithmetic on null pointer}} 324 else 325 a++; // both-note {{arithmetic on null pointer}} 326 return 1; 327 } 328 static_assert(nullptr1(true) == 1, ""); // both-error {{not an integral constant expression}} \ 329 // both-note {{in call to}} 330 331 static_assert(nullptr1(false) == 1, ""); // both-error {{not an integral constant expression}} \ 332 // both-note {{in call to}} 333 }; 334 335 namespace ZeroInit { 336 struct A { 337 int *p[2]; 338 }; 339 constexpr A a = {}; 340 static_assert(a.p[0] == nullptr, ""); 341 static_assert(a.p[1] == nullptr, ""); 342 343 struct B { 344 double f[2]; 345 }; 346 constexpr B b = {}; 347 static_assert(b.f[0] == 0.0, ""); 348 static_assert(b.f[1] == 0.0, ""); 349 } 350 351 namespace ArrayInitLoop { 352 struct X { 353 int arr[3]; 354 }; 355 constexpr X f(int &r) { 356 return {++r, ++r, ++r}; 357 } 358 constexpr int g() { 359 int n = 0; 360 auto [a, b, c] = f(n).arr; 361 return a + b + c; 362 } 363 static_assert(g() == 6, ""); 364 } 365 366 namespace StringZeroFill { 367 struct A { 368 char c[6]; 369 }; 370 constexpr A a = { "abc" }; 371 static_assert(a.c[0] == 'a', ""); 372 static_assert(a.c[1] == 'b', ""); 373 static_assert(a.c[2] == 'c', ""); 374 static_assert(a.c[3] == '\0', ""); 375 static_assert(a.c[4] == '\0', ""); 376 static_assert(a.c[5] == '\0', ""); 377 378 constexpr char b[6] = "foo"; 379 static_assert(b[0] == 'f', ""); 380 static_assert(b[1] == 'o', ""); 381 static_assert(b[2] == 'o', ""); 382 static_assert(b[3] == '\0', ""); 383 static_assert(b[4] == '\0', ""); 384 static_assert(b[5] == '\0', ""); 385 } 386 387 namespace NoInitMapLeak { 388 #pragma clang diagnostic push 389 #pragma clang diagnostic ignored "-Wdivision-by-zero" 390 #pragma clang diagnostic ignored "-Wc++20-extensions" 391 constexpr int testLeak() { // both-error {{never produces a constant expression}} 392 int a[2]; 393 a[0] = 1; 394 // interrupts interpretation. 395 (void)(1 / 0); // both-note 2{{division by zero}} 396 397 return 1; 398 } 399 #pragma clang diagnostic pop 400 static_assert(testLeak() == 1, ""); // both-error {{not an integral constant expression}} \ 401 // both-note {{in call to 'testLeak()'}} 402 403 constexpr int a[] = {1,2,3,4/0,5}; // both-error {{must be initialized by a constant expression}} \ 404 // both-note {{division by zero}} \ 405 // ref-note {{declared here}} 406 407 /// FIXME: This should fail in the new interpreter as well. 408 constexpr int b = a[0]; // ref-error {{must be initialized by a constant expression}} \ 409 // ref-note {{is not a constant expression}} \ 410 // ref-note {{declared here}} 411 static_assert(b == 1, ""); // ref-error {{not an integral constant expression}} \ 412 // ref-note {{not a constant expression}} 413 414 constexpr int f() { // both-error {{never produces a constant expression}} 415 int a[] = {19,2,3/0,4}; // both-note 2{{division by zero}} \ 416 // both-warning {{is undefined}} 417 return 1; 418 } 419 static_assert(f() == 1, ""); // both-error {{not an integral constant expression}} \ 420 // both-note {{in call to}} 421 } 422 423 namespace Incomplete { 424 struct Foo { 425 char c; 426 int a[]; 427 }; 428 429 constexpr Foo F{}; 430 constexpr const int *A = F.a; // both-error {{must be initialized by a constant expression}} \ 431 // both-note {{array-to-pointer decay of array member without known bound}} 432 433 constexpr const int *B = F.a + 1; // both-error {{must be initialized by a constant expression}} \ 434 // both-note {{array-to-pointer decay of array member without known bound}} 435 436 constexpr int C = *F.a; // both-error {{must be initialized by a constant expression}} \ 437 // both-note {{array-to-pointer decay of array member without known bound}} 438 439 struct X { 440 int a; 441 int b[]; 442 }; 443 extern X x; 444 constexpr int *xb = x.b; // both-error {{must be initialized by a constant expression}} \ 445 // both-note {{array-to-pointer decay of array member without known bound}} 446 447 448 /// These are from test/SemaCXX/constant-expression-cxx11.cpp 449 extern int arr[]; 450 constexpr int *c = &arr[1]; // both-error {{must be initialized by a constant expression}} \ 451 // both-note {{indexing of array without known bound}} 452 constexpr int *d = &arr[1]; // both-error {{must be initialized by a constant expression}} \ 453 // both-note {{indexing of array without known bound}} 454 constexpr int *e = arr + 1; // both-error {{must be initialized by a constant expression}} \ 455 // both-note {{indexing of array without known bound}} 456 } 457 458 namespace GH69115 { 459 /// This used to crash because we were trying to emit destructors for the 460 /// array. 461 constexpr int foo() { 462 int arr[2][2] = {1, 2, 3, 4}; 463 return 0; 464 } 465 static_assert(foo() == 0, ""); 466 467 /// Test that we still emit the destructors for multi-dimensional 468 /// composite arrays. 469 #if __cplusplus >= 202002L 470 constexpr void assert(bool C) { 471 if (C) 472 return; 473 // Invalid in constexpr. 474 (void)(1 / 0); // both-warning {{undefined}} 475 } 476 477 class F { 478 public: 479 int a; 480 int *dtor; 481 int &idx; 482 constexpr F(int a, int *dtor, int &idx) : a(a), dtor(dtor), idx(idx) {} 483 constexpr ~F() noexcept(false){ 484 dtor[idx] = a; 485 ++idx; 486 } 487 }; 488 constexpr int foo2() { 489 int dtorIndices[] = {0, 0, 0, 0}; 490 int idx = 0; 491 492 { 493 F arr[2][2] = {F(1, dtorIndices, idx), 494 F(2, dtorIndices, idx), 495 F(3, dtorIndices, idx), 496 F(4, dtorIndices, idx)}; 497 } 498 499 /// Reverse-reverse order. 500 assert(idx == 4); 501 assert(dtorIndices[0] == 4); 502 assert(dtorIndices[1] == 3); 503 assert(dtorIndices[2] == 2); 504 assert(dtorIndices[3] == 1); 505 506 return 0; 507 } 508 static_assert(foo2() == 0, ""); 509 #endif 510 } 511 512 namespace NonConstReads { 513 #if __cplusplus >= 202002L 514 void *p = nullptr; // both-note {{declared here}} 515 516 int arr[!p]; // both-error {{not allowed at file scope}} \ 517 // both-warning {{variable length arrays}} \ 518 // both-note {{read of non-constexpr variable 'p'}} 519 int z; // both-note {{declared here}} 520 int a[z]; // both-error {{not allowed at file scope}} \ 521 // both-warning {{variable length arrays}} \ 522 // both-note {{read of non-const variable 'z'}} 523 #else 524 void *p = nullptr; 525 int arr[!p]; // both-error {{not allowed at file scope}} 526 int z; 527 int a[z]; // both-error {{not allowed at file scope}} 528 #endif 529 530 const int y = 0; 531 int yy[y]; 532 } 533 534 namespace SelfComparison { 535 struct S { 536 int field; 537 static int static_field; 538 int array[4]; 539 }; 540 541 struct T { 542 int field; 543 static int static_field; 544 int array[4]; 545 S s; 546 }; 547 548 int struct_test(S s1, S s2, S *s3, T t) { 549 return s3->array[t.field] == s3->array[t.field]; // both-warning {{self-comparison always evaluates to true}} 550 }; 551 } 552 553 namespace LocalIndex { 554 void test() { 555 const int const_subscript = 3; 556 int array[2]; // both-note {{declared here}} 557 array[const_subscript] = 0; // both-warning {{array index 3 is past the end of the array (that has type 'int[2]')}} 558 } 559 } 560 561 namespace LocalVLA { 562 struct Foo { 563 int x; 564 Foo(int x) : x(x) {} 565 }; 566 struct Elidable { 567 Elidable(); 568 }; 569 570 void foo(int size) { 571 Elidable elidableDynArray[size]; 572 #if __cplusplus >= 202002L 573 // both-note@-3 {{declared here}} 574 // both-warning@-3 {{variable length array}} 575 // both-note@-4 {{function parameter 'size' with unknown value}} 576 #endif 577 } 578 579 void f (unsigned int m) { 580 int e[2][m]; 581 #if __cplusplus >= 202002L 582 // both-note@-3 {{declared here}} 583 // both-warning@-3 2{{variable length array}} 584 // both-note@-4 {{function parameter 'm' with unknown value}} 585 #endif 586 e[0][0] = 0; 587 } 588 } 589 590 char melchizedek[2]; 591 typedef decltype(melchizedek[1] - melchizedek[0]) ptrdiff_t; 592 constexpr ptrdiff_t d1 = &melchizedek[1] - &melchizedek[0]; // ok 593 constexpr ptrdiff_t d3 = &melchizedek[0] - &melchizedek[1]; // ok 594 595 /// GH#88018 596 const int SZA[] = {}; 597 void testZeroSizedArrayAccess() { unsigned c = SZA[4]; } 598 599 #if __cplusplus >= 202002L 600 constexpr int test_multiarray2() { // both-error {{never produces a constant expression}} 601 int multi2[2][1]; // both-note {{declared here}} 602 return multi2[2][0]; // both-note {{cannot access array element of pointer past the end of object}} \ 603 // both-warning {{array index 2 is past the end of the array (that has type 'int[2][1]')}} 604 } 605 606 /// Same but with a dummy pointer. 607 int multi22[2][2]; // both-note {{declared here}} 608 int test_multiarray22() { 609 return multi22[2][0]; // both-warning {{array index 2 is past the end of the array (that has type 'int[2][2]')}} 610 } 611 612 #endif 613 614 namespace ArrayMemberAccess { 615 struct A { 616 int x; 617 }; 618 void f(const A (&a)[]) { 619 bool cond = a->x; 620 } 621 } 622 623 namespace OnePastEndSub { 624 struct A {}; 625 constexpr A a[3][3]; 626 constexpr int diff2 = &a[1][3] - &a[1][0]; /// Used to crash. 627 } 628 629 static int same_entity_2[3]; 630 constexpr int *get2() { 631 // This is a redeclaration of the same entity, even though it doesn't 632 // inherit the type of the prior declaration. 633 extern int same_entity_2[]; 634 return same_entity_2; 635 } 636 static_assert(get2() == same_entity_2, "failed to find previous decl"); 637 638 constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 639 constexpr int fail(const int &p) { 640 return (&p)[64]; // both-note {{cannot refer to element 64 of array of 2 elements}} 641 } 642 static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2)) == 11, ""); // both-error {{not an integral constant expression}} \ 643 // both-note {{in call to}} 644 645 namespace ZeroSizeTypes { 646 constexpr int (*p1)[0] = 0, (*p2)[0] = 0; 647 constexpr int k = p2 - p1; // both-error {{constexpr variable 'k' must be initialized by a constant expression}} \ 648 // both-note {{subtraction of pointers to type 'int[0]' of zero size}} \ 649 // both-warning {{subtraction of pointers to type 'int[0]' of zero size has undefined behavior}} 650 651 int arr[5][0]; 652 constexpr int f() { // both-error {{never produces a constant expression}} 653 return &arr[3] - &arr[0]; // both-note {{subtraction of pointers to type 'int[0]' of zero size}} \ 654 // both-warning {{subtraction of pointers to type 'int[0]' of zero size has undefined behavior}} 655 } 656 } 657