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
7 constexpr const int *foo
[][5] = {
8 {nullptr, &m
, nullptr, nullptr, nullptr},
9 {nullptr, nullptr, &m
, nullptr, nullptr},
10 {nullptr, nullptr, nullptr, &m
, nullptr},
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, "");
29 constexpr int afterEnd
[] = {1,2,3};
30 static_assert(&afterEnd
[3] == afterEnd
+ 3, "");
32 constexpr int ZeroSizeArray
[] = {};
34 constexpr int SomeInt
[] = {1};
35 constexpr int getSomeInt() { return *SomeInt
; }
36 static_assert(getSomeInt() == 1, "");
38 /// A init list for a primitive value.
40 static_assert(f
== 5, "");
43 constexpr int getElement(int i
) {
44 int values
[] = {1, 4, 9, 16, 25, 36};
47 static_assert(getElement(1) == 4, "");
48 static_assert(getElement(5) == 36, "");
50 constexpr int data
[] = {5, 4, 3, 2, 1};
51 constexpr int getElement(const int *Arr
, int index
) {
52 return *(Arr
+ index
);
55 constexpr int derefPtr(const int *d
) {
58 static_assert(derefPtr(data
) == 5, "");
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, "");
64 constexpr int storePtr() {
71 static_assert(storePtr() == 4, "");
74 static_assert(getElement(data
, 1) == 4, "");
75 static_assert(getElement(data
, 4) == 1, "");
77 constexpr int getElementFromEnd(const int *Arr
, int size
, int index
) {
78 return *(Arr
+ size
- index
- 1);
80 static_assert(getElementFromEnd(data
, 5, 0) == 1, "");
81 static_assert(getElementFromEnd(data
, 5, 4) == 5, "");
83 constexpr int getFirstElem(const int *a
) {
84 return a
[0]; // both-note {{read of dereferenced null pointer}}
86 static_assert(getFirstElem(nullptr) == 1, ""); // both-error {{not an integral constant expression}} \
87 // both-note {{in call to}}
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}}
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}}
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, "");
109 constexpr int k2
= &arr2
[1] - &arr
[0]; // both-error {{must be initialized by a constant expression}}
111 static_assert((arr
+ 0) == arr
, "");
112 static_assert(&arr
[0] == arr
, "");
113 static_assert(*(&arr
[0]) == 1, "");
114 static_assert(*(&arr
[1]) == 2, "");
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}}
120 constexpr T
getElementOf(T
* array
, int i
) {
123 static_assert(getElementOf(foo
[0], 1) == &m
, "");
126 template <typename T
, int N
>
127 constexpr T
& getElementOfArray(T (&array
)[N
], int I
) {
130 static_assert(getElementOfArray(foo
[2], 3) == &m
, "");
133 static_assert(data
[0] == 4, ""); // both-error{{failed}} \
134 // both-note{{5 == 4}}
136 constexpr int dynamic
[] = {
137 f
, 3, 2 + 5, data
[3], *getElementOf(foo
[2], 3)
139 static_assert(dynamic
[0] == f
, "");
140 static_assert(dynamic
[3] == 2, "");
143 constexpr int dependent
[4] = {
144 0, 1, dependent
[0], dependent
[1]
146 static_assert(dependent
[2] == dependent
[0], "");
147 static_assert(dependent
[3] == dependent
[1], "");
149 union { char x
[]; } r
= {0};
151 #pragma clang diagnostic push
152 #pragma clang diagnostic ignored "-Wc99-extensions"
153 #pragma clang diagnostic ignored "-Winitializer-overrides"
154 constexpr int DI
[] = {
161 static_assert(DI
[0] == 10, "");
162 static_assert(DI
[1] == 50, "");
163 static_assert(DI
[2] == 30, "");
164 static_assert(DI
[3] == 40, "");
166 constexpr int addThreeElements(const int v
[3]) {
167 return v
[0] + v
[1] + v
[2];
169 constexpr int is
[] = {10, 20, 30 };
170 static_assert(addThreeElements(is
) == 60, "");
177 struct fred y
[] = { [0] = { .s
[0] = 'q' } };
178 #pragma clang diagnostic pop
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}}
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}} \
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}}
193 namespace DefaultInit
{
194 template <typename T
, unsigned N
>
200 constexpr B
<int,10> arr
= {};
201 constexpr int x
= arr
.a
[0];
208 constexpr A(int m
= 2) : a(10 + m
) {}
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}}
223 static_assert(b
.a
[0].a
== 12, "");
224 static_assert(b
.a
[1].a
== 12, "");
229 constexpr BU() {} // both-note {{in call to 'AU()'}}
231 constexpr BU bu
; // both-error {{must be initialized by a constant expression}} \
232 // both-note {{in call to 'BU()'}}
235 constexpr int getNextElem(const int *A
, int I
) {
236 const int *B
= (A
+ I
);
240 constexpr int E
[] = {1,2,3,4};
242 static_assert(getNextElem(E
, 1) == 3, "");
244 constexpr int getFirst() {
248 static_assert(getFirst() == 1, "");
250 constexpr int getFirst2() {
255 static_assert(getFirst2() == 2, "");
257 constexpr int getSecond() {
261 static_assert(getSecond() == 2, "");
263 constexpr int getSecond2() {
268 static_assert(getSecond2() == 2, "");
270 constexpr int getLast() {
271 const int *e
= E
+ 3;
274 static_assert(getLast() == 4, "");
276 constexpr int getLast2() {
277 const int *e
= E
+ 3;
281 static_assert(getLast2() == 3, "");
283 constexpr int getSecondToLast() {
284 const int *e
= E
+ 3;
287 static_assert(getSecondToLast() == 3, "");
289 constexpr int getSecondToLast2() {
290 const int *e
= E
+ 3;
294 static_assert(getSecondToLast2() == 3, "");
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}}
301 static_assert(bad1() == 0, ""); // both-error {{not an integral constant expression}} \
302 // both-note {{in call to}}
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
309 static_assert(bad2() == 0, ""); // both-error {{not an integral constant expression}} \
310 // both-note {{in call to}}
312 constexpr int bad3() { // both-error {{never produces a constant expression}}
314 e
--; // both-note 2{{cannot refer to element -1 of array of 4 elements}}
315 return *e
; // This is UB as well
317 static_assert(bad3() == 0, ""); // both-error {{not an integral constant expression}} \
318 // both-note {{in call to}}
320 constexpr int nullptr1(bool Pre
) {
323 ++a
; // both-note {{arithmetic on null pointer}}
325 a
++; // both-note {{arithmetic on null pointer}}
328 static_assert(nullptr1(true) == 1, ""); // both-error {{not an integral constant expression}} \
329 // both-note {{in call to}}
331 static_assert(nullptr1(false) == 1, ""); // both-error {{not an integral constant expression}} \
332 // both-note {{in call to}}
340 static_assert(a
.p
[0] == nullptr, "");
341 static_assert(a
.p
[1] == nullptr, "");
347 static_assert(b
.f
[0] == 0.0, "");
348 static_assert(b
.f
[1] == 0.0, "");
351 namespace ArrayInitLoop
{
355 constexpr X
f(int &r
) {
356 return {++r
, ++r
, ++r
};
360 auto [a
, b
, c
] = f(n
).arr
;
363 static_assert(g() == 6, "");
366 namespace StringZeroFill
{
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', "");
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', "");
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}}
394 // interrupts interpretation.
395 (void)(1 / 0); // both-note 2{{division by zero}}
399 #pragma clang diagnostic pop
400 static_assert(testLeak() == 1, ""); // both-error {{not an integral constant expression}} \
401 // both-note {{in call to 'testLeak()'}}
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}}
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}}
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}}
419 static_assert(f() == 1, ""); // both-error {{not an integral constant expression}} \
420 // both-note {{in call to}}
423 namespace Incomplete
{
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}}
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}}
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}}
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}}
448 /// These are from test/SemaCXX/constant-expression-cxx11.cpp
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}}
459 /// This used to crash because we were trying to emit destructors for the
461 constexpr int foo() {
462 int arr
[2][2] = {1, 2, 3, 4};
465 static_assert(foo() == 0, "");
467 /// Test that we still emit the destructors for multi-dimensional
468 /// composite arrays.
469 #if __cplusplus >= 202002L
470 constexpr void assert(bool C
) {
473 // Invalid in constexpr.
474 (void)(1 / 0); // both-warning {{undefined}}
482 constexpr F(int a
, int *dtor
, int &idx
) : a(a
), dtor(dtor
), idx(idx
) {}
483 constexpr ~F() noexcept(false){
488 constexpr int foo2() {
489 int dtorIndices
[] = {0, 0, 0, 0};
493 F arr
[2][2] = {F(1, dtorIndices
, idx
),
494 F(2, dtorIndices
, idx
),
495 F(3, dtorIndices
, idx
),
496 F(4, dtorIndices
, idx
)};
499 /// Reverse-reverse order.
501 assert(dtorIndices
[0] == 4);
502 assert(dtorIndices
[1] == 3);
503 assert(dtorIndices
[2] == 2);
504 assert(dtorIndices
[3] == 1);
508 static_assert(foo2() == 0, "");
512 namespace NonConstReads
{
513 #if __cplusplus >= 202002L
514 void *p
= nullptr; // both-note {{declared here}}
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'}}
525 int arr
[!p
]; // both-error {{not allowed at file scope}}
527 int a
[z
]; // both-error {{not allowed at file scope}}
534 namespace SelfComparison
{
537 static int static_field
;
543 static int static_field
;
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}}
553 namespace LocalIndex
{
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]')}}
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}}
579 void f (unsigned int 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}}
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
596 const int SZA
[] = {};
597 void testZeroSizedArrayAccess() { unsigned c
= SZA
[4]; }
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]')}}
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]')}}
614 namespace ArrayMemberAccess
{
618 void f(const A (&a
)[]) {
623 namespace OnePastEndSub
{
626 constexpr int diff2
= &a
[1][3] - &a
[1][0]; /// Used to crash.
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
;
636 static_assert(get2() == same_entity_2
, "failed to find previous decl");
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}}
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}}
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}}
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}}