1 // RUN: %clang_cc1 -fcxx-exceptions -fexperimental-new-constant-interpreter -std=c++20 -verify %s
2 // RUN: %clang_cc1 -fcxx-exceptions -std=c++20 -verify=ref %s
4 void test_alignas_operand() {
6 static_assert(__alignof(dummy
) == 8);
9 constexpr int getMinus5() {
15 static_assert(getMinus5() == -5, "");
17 constexpr int assign() {
25 static_assert(assign() == 20, "");
28 constexpr int pointerAssign() {
32 *p
= 12; // modifies m
36 static_assert(pointerAssign() == 12, "");
38 constexpr int pointerDeref() {
44 static_assert(pointerDeref() == 12, "");
46 constexpr int pointerAssign2() {
57 static_assert(pointerAssign2() == 12, "");
59 constexpr int unInitLocal() {
61 return a
; // ref-note {{read of uninitialized object}} \
62 // expected-note {{read of uninitialized object}}
64 static_assert(unInitLocal() == 0, ""); // ref-error {{not an integral constant expression}} \
65 // ref-note {{in call to 'unInitLocal()'}} \
66 // expected-error {{not an integral constant expression}} \
67 // expected-note {{in call to 'unInitLocal()'}} \
69 constexpr int initializedLocal() {
74 static_assert(initializedLocal() == 20);
76 constexpr int initializedLocal2() {
78 return *a
; // expected-note {{read of uninitialized object is not allowed in a constant expression}} \
79 // ref-note {{read of uninitialized object is not allowed in a constant expression}}
81 static_assert(initializedLocal2() == 20); // expected-error {{not an integral constant expression}} \
82 // expected-note {{in call to}} \
83 // ref-error {{not an integral constant expression}} \
84 // ref-note {{in call to}}
87 struct Int
{ int a
; };
88 constexpr int initializedLocal3() {
90 return i
.a
; // ref-note {{read of uninitialized object is not allowed in a constant expression}} \
91 // expected-note {{read of uninitialized object}}
93 static_assert(initializedLocal3() == 20); // expected-error {{not an integral constant expression}} \
94 // expected-note {{in call to}} \
95 // ref-error {{not an integral constant expression}} \
96 // ref-note {{in call to}}
101 // FIXME: This code should be rejected because we pass an uninitialized value
102 // as a function parameter.
103 constexpr int inc(int a
) { return a
+ 1; }
111 /// Distinct literals have disctinct addresses.
112 /// see https://github.com/llvm/llvm-project/issues/58754
113 constexpr auto foo(const char *p
) { return p
; }
114 constexpr auto p1
= "test1";
115 constexpr auto p2
= "test2";
117 constexpr bool b1
= foo(p1
) == foo(p1
);
120 constexpr bool b2
= foo(p1
) == foo(p2
); // ref-error {{must be initialized by a constant expression}} \
121 // ref-note {{comparison of addresses of literals}} \
122 // ref-note {{declared here}}
123 static_assert(!b2
); // ref-error {{not an integral constant expression}} \
124 // ref-note {{not a constant expression}}
126 constexpr auto name1() { return "name1"; }
127 constexpr auto name2() { return "name2"; }
129 constexpr auto b3
= name1() == name1();
131 constexpr auto b4
= name1() == name2(); // ref-error {{must be initialized by a constant expression}} \
132 // ref-note {{has unspecified value}} \
133 // ref-note {{declared here}}
134 static_assert(!b4
); // ref-error {{not an integral constant expression}} \
135 // ref-note {{not a constant expression}}
137 namespace UninitializedFields
{
140 int a
; // expected-note 4{{subobject declared here}} \
141 // ref-note 4{{subobject declared here}}
144 constexpr A a
; // expected-error {{must be initialized by a constant expression}} \
145 // expected-note {{subobject 'a' is not initialized}} \
146 // ref-error {{must be initialized by a constant expression}} \
147 // ref-note {{subobject 'a' is not initialized}}
148 constexpr A aarr
[2]; // expected-error {{must be initialized by a constant expression}} \
149 // expected-note {{subobject 'a' is not initialized}} \
150 // ref-error {{must be initialized by a constant expression}} \
151 // ref-note {{subobject 'a' is not initialized}}
154 int f
; // expected-note 3{{subobject declared here}} \
155 // ref-note 3{{subobject declared here}}
158 constexpr F(bool b
) {
164 constexpr F foo
[2] = {true}; // expected-error {{must be initialized by a constant expression}} \
165 // expected-note {{subobject 'f' is not initialized}} \
166 // ref-error {{must be initialized by a constant expression}} \
167 // ref-note {{subobject 'f' is not initialized}}
168 constexpr F foo2
[3] = {true, false, true}; // expected-error {{must be initialized by a constant expression}} \
169 // expected-note {{subobject 'f' is not initialized}} \
170 // ref-error {{must be initialized by a constant expression}} \
171 // ref-note {{subobject 'f' is not initialized}}
172 constexpr F foo3
[3] = {true, true, F()}; // expected-error {{must be initialized by a constant expression}} \
173 // expected-note {{subobject 'f' is not initialized}} \
174 // ref-error {{must be initialized by a constant expression}} \
175 // ref-note {{subobject 'f' is not initialized}}
182 int a
; // expected-note {{subobject declared here}} \
183 // ref-note {{subobject declared here}}
184 constexpr Base() : b(true) {}
187 class Derived
: public Base
{
189 constexpr Derived() : Base() {} };
191 constexpr Derived D
; // expected-error {{must be initialized by a constant expression}} \
192 // expected-note {{subobject 'a' is not initialized}} \
193 // ref-error {{must be initialized by a constant expression}} \
194 // ref-note {{subobject 'a' is not initialized}}
200 constexpr C2 c2
; // expected-error {{must be initialized by a constant expression}} \
201 // expected-note {{subobject 'a' is not initialized}} \
202 // ref-error {{must be initialized by a constant expression}} \
203 // ref-note {{subobject 'a' is not initialized}}
210 constexpr C3 c3
; // expected-error {{must be initialized by a constant expression}} \
211 // expected-note {{subobject 'a' is not initialized}} \
212 // ref-error {{must be initialized by a constant expression}} \
213 // ref-note {{subobject 'a' is not initialized}}
217 bool B
[2][3]; // expected-note {{subobject declared here}} \
218 // ref-note {{subobject declared here}}
221 constexpr C4 c4
; // expected-error {{must be initialized by a constant expression}} \
222 // expected-note {{subobject 'B' is not initialized}} \
223 // ref-error {{must be initialized by a constant expression}} \
224 // ref-note {{subobject 'B' is not initialized}}
227 namespace ConstThis
{
229 const int T
= 12; // expected-note {{declared const here}} \
230 // ref-note {{declared const here}}
233 constexpr Foo() { // expected-note {{declared here}}
235 T
= 13; // expected-error {{cannot assign to non-static data member 'T' with const-qualified type}} \
236 // ref-error {{cannot assign to non-static data member 'T' with const-qualified type}}
239 constexpr Foo F
; // expected-error {{must be initialized by a constant expression}} \
240 // FIXME: The following note is wrong. \
241 // expected-note {{undefined constructor 'Foo' cannot be used in a constant expression}} \
242 // ref-error {{must be initialized by a constant expression}}
248 constexpr FooDtor() {
251 constexpr ~FooDtor() {
256 constexpr int foo() {
260 static_assert(foo() == 0);
266 constexpr ctor_test() {
269 int local
= 100 / a
; // expected-note {{division by zero}} \
270 // ref-note {{division by zero}}
278 constexpr dtor_test() = default;
279 constexpr ~dtor_test() {
282 int local
= 100 / a
; // expected-note {{division by zero}} \
283 // ref-note {{division by zero}}
287 constexpr ctor_test
<true> good_ctor
;
288 constexpr dtor_test
<true> good_dtor
;
290 constexpr ctor_test
<false> bad_ctor
; // expected-error {{must be initialized by a constant expression}} \
291 // expected-note {{in call to}} \
292 // ref-error {{must be initialized by a constant expression}} \
293 // ref-note {{in call to}}
294 constexpr dtor_test
<false> bad_dtor
; // expected-error {{must have constant destruction}} \
295 // expected-note {{in call to}} \
296 // ref-error {{must have constant destruction}} \
297 // ref-note {{in call to}}
305 struct Intermediate
: Base
{
309 struct Final
: Intermediate
{
312 constexpr Final(int a
, int b
, int c
) : c(c
) {}
315 static_assert(Final
{1, 2, 3}.c
== 3, ""); // OK
316 static_assert(Final
{1, 2, 3}.a
== 0, ""); // expected-error {{not an integral constant expression}} \
317 // expected-note {{read of uninitialized object}} \
318 // ref-error {{not an integral constant expression}} \
319 // ref-note {{read of uninitialized object}}
325 constexpr Mixin() = default;
326 constexpr Mixin(int b
) : b(b
) {}
329 struct Final2
: Base
, Mixin
{
332 constexpr Final2(int a
, int b
, int c
) : Mixin(b
), c(c
) {}
333 constexpr Final2(int a
, int b
, int c
, bool) : c(c
) {}
336 static_assert(Final2
{1, 2, 3}.c
== 3, ""); // OK
337 static_assert(Final2
{1, 2, 3}.b
== 2, ""); // OK
338 static_assert(Final2
{1, 2, 3}.a
== 0, ""); // expected-error {{not an integral constant expression}} \
339 // expected-note {{read of uninitialized object}} \
340 // ref-error {{not an integral constant expression}} \
341 // ref-note {{read of uninitialized object}}
348 struct Final3
: Base
, Mixin3
{
351 constexpr Final3(int a
, int b
, int c
) : c(c
) { this->b
= b
; }
352 constexpr Final3(int a
, int b
, int c
, bool) : c(c
) {}
355 static_assert(Final3
{1, 2, 3}.c
== 3, ""); // OK
356 static_assert(Final3
{1, 2, 3}.b
== 2, ""); // OK
357 static_assert(Final3
{1, 2, 3}.a
== 0, ""); // expected-error {{not an integral constant expression}} \
358 // expected-note {{read of uninitialized object}} \
359 // ref-error {{not an integral constant expression}} \
360 // ref-note {{read of uninitialized object}}
363 namespace Destructors
{
368 constexpr Inc(int &I
) : I(I
) {}
377 constexpr Dec(int &I
) : I(I
) {}
394 static_assert(m() == 3, "");
407 static_assert(C() == 10, "");
423 static_assert(D() == 0, "");
434 static_assert(E() == 1, "");
437 /// FIXME: This should be rejected, since we call the destructor
438 /// twice. However, GCC doesn't care either.
439 constexpr int ManualDtor() {
442 Inc
I(i
); // ref-note {{destroying object 'I' whose lifetime has already ended}}
447 static_assert(ManualDtor() == 1, ""); // expected-error {{static assertion failed}} \
448 // expected-note {{evaluates to '2 == 1'}} \
449 // ref-error {{not an integral constant expression}} \
450 // ref-note {{in call to 'ManualDtor()'}}
452 constexpr void doInc(int &i
) {
456 constexpr int testInc() {
461 static_assert(testInc() == 1, "");
462 constexpr void doInc2(int &i
) {
464 // No return statement.
466 constexpr int testInc2() {
471 static_assert(testInc2() == 1, "");
474 namespace DtorOrder
{
478 constexpr A(int &I
) : I(I
) {}
486 constexpr B(int &I
) : A(I
) {}
492 constexpr int foo() {
500 static_assert(foo() == 1337);
507 constexpr FieldDtor1(int &I
) : I1(I
), I2(I
){}
510 constexpr int foo2() {
518 static_assert(foo2() == 2);
523 constexpr FieldDtor2(int &I
) : Incs
{Inc(I
), Inc(I
), Inc(I
)} {}
526 constexpr int foo3() {
534 static_assert(foo3() == 3);
545 constexpr bool ArrayOrder() {
546 int order
[3] = {0, 0, 0};
554 // ds will be destroyed.
556 return order
[0] == 3 && order
[1] == 2 && order
[2] == 1;
558 static_assert(ArrayOrder());
561 // Static members aren't destroyed.
571 static constexpr Dec2 a
;
574 static_assert(Foo::a
.A
== 0);
579 static_assert(Foo::a
.A
== 0);
581 static_assert(Foo::a
.A
== 0);
584 struct NotConstexpr
{
590 constexpr Outer() = default;
593 constexpr int foo() {
597 constexpr int bar()const {
598 return Outer
{}.foo();
601 static NotConstexpr Val
;
604 constexpr Outer::~Outer() {}
607 static_assert(O
.bar() == 12);
610 namespace BaseAndFieldInit
{
623 constexpr C c
= {1,2,3};
624 static_assert(c
.a
== 1 && c
.b
== 2 && c
.c
== 3);
627 namespace ImplicitFunction
{
629 int a
; // ref-note {{subobject declared here}}
632 constexpr int callMe() {
636 /// The operator= call here will fail and the diagnostics should be fine.
637 b
= a
; // ref-note {{subobject 'a' is not initialized}} \
638 // ref-note {{in call to}} \
639 // expected-note {{read of uninitialized object}} \
640 // expected-note {{in call to}}
644 static_assert(callMe() == 1, ""); // ref-error {{not an integral constant expression}} \
645 // ref-note {{in call to 'callMe()'}} \
646 // expected-error {{not an integral constant expression}} \
647 // expected-note {{in call to 'callMe()'}}
650 /// FIXME: Unfortunately, the similar tests in test/SemaCXX/{compare-cxx2a.cpp use member pointers,
651 /// which we don't support yet.
653 class strong_ordering
{
656 static const strong_ordering less
, equal
, greater
;
657 constexpr bool operator==(int n
) const noexcept
{ return this->n
== n
;}
658 constexpr bool operator!=(int n
) const noexcept
{ return this->n
!= n
;}
660 constexpr strong_ordering
strong_ordering::less
= {-1};
661 constexpr strong_ordering
strong_ordering::equal
= {0};
662 constexpr strong_ordering
strong_ordering::greater
= {1};
664 class partial_ordering
{
667 static const partial_ordering less
, equal
, greater
, equivalent
, unordered
;
668 constexpr bool operator==(long n
) const noexcept
{ return this->n
== n
;}
669 constexpr bool operator!=(long n
) const noexcept
{ return this->n
!= n
;}
671 constexpr partial_ordering
partial_ordering::less
= {-1};
672 constexpr partial_ordering
partial_ordering::equal
= {0};
673 constexpr partial_ordering
partial_ordering::greater
= {1};
674 constexpr partial_ordering
partial_ordering::equivalent
= {0};
675 constexpr partial_ordering
partial_ordering::unordered
= {-127};
678 namespace ThreeWayCmp
{
679 static_assert(1 <=> 2 == -1, "");
680 static_assert(1 <=> 1 == 0, "");
681 static_assert(2 <=> 1 == 1, "");
682 static_assert(1.0 <=> 2.f
== -1, "");
683 static_assert(1.0 <=> 1.0 == 0, "");
684 static_assert(2.0 <=> 1.0 == 1, "");
685 constexpr int k
= (1 <=> 1, 0); // expected-warning {{comparison result unused}} \
686 // ref-warning {{comparison result unused}}
687 static_assert(k
== 0, "");
690 constexpr int a
[] = {1,2,3};
691 constexpr int b
[] = {1,2,3};
692 constexpr const int *pa1
= &a
[1];
693 constexpr const int *pa2
= &a
[2];
694 constexpr const int *pb1
= &b
[1];
695 static_assert(pa1
<=> pb1
!= 0, ""); // expected-error {{not an integral constant expression}} \
696 // expected-note {{has unspecified value}} \
697 // ref-error {{not an integral constant expression}} \
698 // ref-note {{has unspecified value}}
699 static_assert(pa1
<=> pa1
== 0, "");
700 static_assert(pa1
<=> pa2
== -1, "");
701 static_assert(pa2
<=> pa1
== 1, "");
704 namespace ConstexprArrayInitLoopExprDestructors
708 constexpr Highlander() {}
709 constexpr void set(int *p
) { this->p
= p
; ++*p
; if (*p
!= 1) throw "there can be only one"; }
710 constexpr ~Highlander() { --*p
; }
715 constexpr X(int *p
) : p(p
) {}
716 constexpr X(const X
&x
, Highlander
&&h
= Highlander()) : p(x
.p
) {
723 X x
[3] = {&n
, &n
, &n
};
728 static_assert(f() == 0);
731 namespace NonPrimitiveOpaqueValue
735 constexpr operator bool() const { return x
!= 0; }
738 constexpr int ternary() { return X(0) ?: X(0); }
740 static_assert(!ternary(), "");
744 constexpr int foo() {
753 static_assert(foo() == 11);