[flang][cuda] Adapt ExternalNameConversion to work in gpu module (#117039)
[llvm-project.git] / clang / test / AST / ByteCode / cxx20.cpp
blobdea4055c531d23b8a31fc71b89a49783310270b6
1 // RUN: %clang_cc1 -fcxx-exceptions -fexperimental-new-constant-interpreter -std=c++20 -verify=both,expected -fcxx-exceptions %s
2 // RUN: %clang_cc1 -fcxx-exceptions -std=c++20 -verify=both,ref -fcxx-exceptions %s
4 void test_alignas_operand() {
5 alignas(8) char dummy;
6 static_assert(__alignof(dummy) == 8);
9 constexpr int getMinus5() {
10 int a = 10;
11 a = -5;
12 int *p = &a;
13 return *p;
15 static_assert(getMinus5() == -5, "");
17 constexpr int assign() {
18 int m = 10;
19 int k = 12;
21 m = (k = 20);
23 return m;
25 static_assert(assign() == 20, "");
28 constexpr int pointerAssign() {
29 int m = 10;
30 int *p = &m;
32 *p = 12; // modifies m
34 return m;
36 static_assert(pointerAssign() == 12, "");
38 constexpr int pointerDeref() {
39 int m = 12;
40 int *p = &m;
42 return *p;
44 static_assert(pointerDeref() == 12, "");
46 constexpr int pointerAssign2() {
47 int m = 10;
48 int *p = &m;
49 int **pp = &p;
51 **pp = 12;
53 int v = **pp;
55 return v;
57 static_assert(pointerAssign2() == 12, "");
59 constexpr int unInitLocal() {
60 int a;
61 return a; // both-note {{read of uninitialized object}}
63 static_assert(unInitLocal() == 0, ""); // both-error {{not an integral constant expression}} \
64 // both-note {{in call to 'unInitLocal()'}}
66 constexpr int initializedLocal() {
67 int a;
68 a = 20;
69 return a;
71 static_assert(initializedLocal() == 20);
73 constexpr int initializedLocal2() {
74 int a[2];
75 return *a; // both-note {{read of uninitialized object is not allowed in a constant expression}}
77 static_assert(initializedLocal2() == 20); // both-error {{not an integral constant expression}} \
78 // both-note {{in call to}}
81 struct Int { int a; };
82 constexpr int initializedLocal3() {
83 Int i;
84 return i.a; // both-note {{read of uninitialized object is not allowed in a constant expression}}
86 static_assert(initializedLocal3() == 20); // both-error {{not an integral constant expression}} \
87 // both-note {{in call to}}
91 #if 0
92 // FIXME: This code should be rejected because we pass an uninitialized value
93 // as a function parameter.
94 constexpr int inc(int a) { return a + 1; }
95 constexpr int f() {
96 int i;
97 return inc(i);
99 static_assert(f());
100 #endif
102 /// Distinct literals have distinct addresses.
103 /// see https://github.com/llvm/llvm-project/issues/58754
104 constexpr auto foo(const char *p) { return p; }
105 constexpr auto p1 = "test1";
106 constexpr auto p2 = "test2";
108 constexpr bool b1 = foo(p1) == foo(p1);
109 static_assert(b1);
111 constexpr bool b2 = foo(p1) == foo(p2);
112 static_assert(!b2);
114 constexpr auto name1() { return "name1"; }
115 constexpr auto name2() { return "name2"; }
117 constexpr auto b3 = name1() == name1(); // ref-error {{must be initialized by a constant expression}} \
118 // ref-note {{comparison of addresses of literals}}
119 constexpr auto b4 = name1() == name2();
120 static_assert(!b4);
122 namespace UninitializedFields {
123 class A {
124 public:
125 int a; // both-note 4{{subobject declared here}}
126 constexpr A() {}
128 constexpr A a; // both-error {{must be initialized by a constant expression}} \
129 // both-note {{subobject 'a' is not initialized}}
130 constexpr A aarr[2]; // both-error {{must be initialized by a constant expression}} \
131 // both-note {{subobject 'a' is not initialized}}
132 class F {
133 public:
134 int f; // both-note 3{{subobject declared here}}
136 constexpr F() {}
137 constexpr F(bool b) {
138 if (b)
139 f = 42;
143 constexpr F foo[2] = {true}; // both-error {{must be initialized by a constant expression}} \
144 // both-note {{subobject 'f' is not initialized}}
145 constexpr F foo2[3] = {true, false, true}; // both-error {{must be initialized by a constant expression}} \
146 // both-note {{subobject 'f' is not initialized}}
147 constexpr F foo3[3] = {true, true, F()}; // both-error {{must be initialized by a constant expression}} \
148 // both-note {{subobject 'f' is not initialized}}
152 class Base {
153 public:
154 bool b;
155 int a; // both-note {{subobject declared here}}
156 constexpr Base() : b(true) {}
159 class Derived : public Base {
160 public:
161 constexpr Derived() : Base() {} };
163 constexpr Derived D; // both-error {{must be initialized by a constant expression}} \
164 // both-note {{subobject 'a' is not initialized}}
166 class C2 {
167 public:
168 A a;
169 constexpr C2() {} };
170 constexpr C2 c2; // both-error {{must be initialized by a constant expression}} \
171 // both-note {{subobject 'a' is not initialized}}
173 class C3 {
174 public:
175 A a[2];
176 constexpr C3() {}
178 constexpr C3 c3; // both-error {{must be initialized by a constant expression}} \
179 // both-note {{subobject 'a' is not initialized}}
181 class C4 {
182 public:
183 bool B[2][3]; // both-note {{subobject declared here}}
184 constexpr C4(){}
186 constexpr C4 c4; // both-error {{must be initialized by a constant expression}} \
187 // both-note {{subobject 'B' is not initialized}}
190 namespace ConstThis {
191 class Foo {
192 const int T = 12; // both-note {{declared const here}}
193 int a;
194 public:
195 constexpr Foo() {
196 this->a = 10;
197 T = 13; // both-error {{cannot assign to non-static data member 'T' with const-qualified type}}
200 constexpr Foo F; // both-error {{must be initialized by a constant expression}}
203 class FooDtor {
204 int a;
205 public:
206 constexpr FooDtor() {
207 this->a = 10;
209 constexpr ~FooDtor() {
210 this->a = 12;
214 constexpr int foo() {
215 const FooDtor f;
216 return 0;
218 static_assert(foo() == 0);
220 template <bool Good>
221 struct ctor_test {
222 int a = 0;
224 constexpr ctor_test() {
225 if (Good)
226 a = 10;
227 int local = 100 / a; // both-note {{division by zero}}
231 template <bool Good>
232 struct dtor_test {
233 int a = 0;
235 constexpr dtor_test() = default;
236 constexpr ~dtor_test() {
237 if (Good)
238 a = 10;
239 int local = 100 / a; // both-note {{division by zero}}
243 constexpr ctor_test<true> good_ctor;
244 constexpr dtor_test<true> good_dtor;
246 constexpr ctor_test<false> bad_ctor; // both-error {{must be initialized by a constant expression}} \
247 // both-note {{in call to}}
248 constexpr dtor_test<false> bad_dtor; // both-error {{must have constant destruction}} \
249 // both-note {{in call to}}
252 namespace BaseInit {
253 struct Base {
254 int a;
257 struct Intermediate : Base {
258 int b;
261 struct Final : Intermediate {
262 int c;
264 constexpr Final(int a, int b, int c) : c(c) {}
267 static_assert(Final{1, 2, 3}.c == 3, ""); // OK
268 static_assert(Final{1, 2, 3}.a == 0, ""); // both-error {{not an integral constant expression}} \
269 // both-note {{read of uninitialized object}}
272 struct Mixin {
273 int b;
275 constexpr Mixin() = default;
276 constexpr Mixin(int b) : b(b) {}
279 struct Final2 : Base, Mixin {
280 int c;
282 constexpr Final2(int a, int b, int c) : Mixin(b), c(c) {}
283 constexpr Final2(int a, int b, int c, bool) : c(c) {}
286 static_assert(Final2{1, 2, 3}.c == 3, ""); // OK
287 static_assert(Final2{1, 2, 3}.b == 2, ""); // OK
288 static_assert(Final2{1, 2, 3}.a == 0, ""); // both-error {{not an integral constant expression}} \
289 // both-note {{read of uninitialized object}}
292 struct Mixin3 {
293 int b;
296 struct Final3 : Base, Mixin3 {
297 int c;
299 constexpr Final3(int a, int b, int c) : c(c) { this->b = b; }
300 constexpr Final3(int a, int b, int c, bool) : c(c) {}
303 static_assert(Final3{1, 2, 3}.c == 3, ""); // OK
304 static_assert(Final3{1, 2, 3}.b == 2, ""); // OK
305 static_assert(Final3{1, 2, 3}.a == 0, ""); // both-error {{not an integral constant expression}} \
306 // both-note {{read of uninitialized object}}
309 namespace Destructors {
311 class Inc final {
312 public:
313 int &I;
314 constexpr Inc(int &I) : I(I) {}
315 constexpr ~Inc() {
316 I++;
320 class Dec final {
321 public:
322 int &I;
323 constexpr Dec(int &I) : I(I) {}
324 constexpr ~Dec() {
325 I--;
331 constexpr int m() {
332 int i = 0;
334 Inc f1(i);
335 Inc f2(i);
336 Inc f3(i);
338 return i;
340 static_assert(m() == 3, "");
343 constexpr int C() {
344 int i = 0;
346 while (i < 10) {
347 Inc inc(i);
348 continue;
349 Dec dec(i);
351 return i;
353 static_assert(C() == 10, "");
356 constexpr int D() {
357 int i = 0;
360 Inc i1(i);
362 Inc i2(i);
363 return i;
367 return i;
369 static_assert(D() == 0, "");
371 constexpr int E() {
372 int i = 0;
374 for(;;) {
375 Inc i1(i);
376 break;
378 return i;
380 static_assert(E() == 1, "");
383 /// FIXME: This should be rejected, since we call the destructor
384 /// twice. However, GCC doesn't care either.
385 constexpr int ManualDtor() {
386 int i = 0;
388 Inc I(i); // ref-note {{destroying object 'I' whose lifetime has already ended}}
389 I.~Inc();
391 return i;
393 static_assert(ManualDtor() == 1, ""); // expected-error {{static assertion failed}} \
394 // expected-note {{evaluates to '2 == 1'}} \
395 // ref-error {{not an integral constant expression}} \
396 // ref-note {{in call to 'ManualDtor()'}}
398 constexpr void doInc(int &i) {
399 Inc I(i);
400 return;
402 constexpr int testInc() {
403 int i = 0;
404 doInc(i);
405 return i;
407 static_assert(testInc() == 1, "");
408 constexpr void doInc2(int &i) {
409 Inc I(i);
410 // No return statement.
412 constexpr int testInc2() {
413 int i = 0;
414 doInc2(i);
415 return i;
417 static_assert(testInc2() == 1, "");
420 namespace DtorOrder {
421 class A {
422 public:
423 int &I;
424 constexpr A(int &I) : I(I) {}
425 constexpr ~A() {
426 I = 1337;
430 class B : public A {
431 public:
432 constexpr B(int &I) : A(I) {}
433 constexpr ~B() {
434 I = 42;
438 constexpr int foo() {
439 int i = 0;
441 B b(i);
443 return i;
446 static_assert(foo() == 1337);
449 class FieldDtor1 {
450 public:
451 Inc I1;
452 Inc I2;
453 constexpr FieldDtor1(int &I) : I1(I), I2(I){}
456 constexpr int foo2() {
457 int i = 0;
459 FieldDtor1 FD1(i);
461 return i;
464 static_assert(foo2() == 2);
466 class FieldDtor2 {
467 public:
468 Inc Incs[3];
469 constexpr FieldDtor2(int &I) : Incs{Inc(I), Inc(I), Inc(I)} {}
472 constexpr int foo3() {
473 int i = 0;
475 FieldDtor2 FD2(i);
477 return i;
480 static_assert(foo3() == 3);
482 struct ArrD {
483 int index;
484 int *arr;
485 int &p;
486 constexpr ~ArrD() {
487 arr[p] = index;
488 ++p;
491 constexpr bool ArrayOrder() {
492 int order[3] = {0, 0, 0};
493 int p = 0;
495 ArrD ds[3] = {
496 {1, order, p},
497 {2, order, p},
498 {3, order, p},
500 // ds will be destroyed.
502 return order[0] == 3 && order[1] == 2 && order[2] == 1;
504 static_assert(ArrayOrder());
507 // Static members aren't destroyed.
508 class Dec2 {
509 public:
510 int A = 0;
511 constexpr ~Dec2() {
512 A++;
515 class Foo {
516 public:
517 static constexpr Dec2 a;
518 static Dec2 b;
520 static_assert(Foo::a.A == 0);
521 constexpr bool f() {
522 Foo f;
523 return true;
525 static_assert(Foo::a.A == 0);
526 static_assert(f());
527 static_assert(Foo::a.A == 0);
530 struct NotConstexpr {
531 NotConstexpr() {}
532 ~NotConstexpr() {}
535 struct Outer {
536 constexpr Outer() = default;
537 constexpr ~Outer();
539 constexpr int foo() {
540 return 12;
543 constexpr int bar()const {
544 return Outer{}.foo();
547 static NotConstexpr Val;
550 constexpr Outer::~Outer() {}
552 constexpr Outer O;
553 static_assert(O.bar() == 12);
556 namespace BaseAndFieldInit {
557 struct A {
558 int a;
561 struct B : A {
562 int b;
565 struct C : B {
566 int c;
569 constexpr C c = {1,2,3};
570 static_assert(c.a == 1 && c.b == 2 && c.c == 3);
573 namespace ImplicitFunction {
574 struct A {
575 int a; // ref-note {{subobject declared here}}
578 constexpr int callMe() {
579 A a;
580 A b{12};
582 /// The operator= call here will fail and the diagnostics should be fine.
583 b = a; // ref-note {{subobject 'a' is not initialized}} \
584 // expected-note {{read of uninitialized object}} \
585 // both-note {{in call to}}
587 return 1;
589 static_assert(callMe() == 1, ""); // both-error {{not an integral constant expression}} \
590 // both-note {{in call to 'callMe()'}}
593 namespace std {
594 class strong_ordering {
595 public:
596 int n;
597 static const strong_ordering less, equal, greater;
598 constexpr bool operator==(int n) const noexcept { return this->n == n;}
599 constexpr bool operator!=(int n) const noexcept { return this->n != n;}
601 constexpr strong_ordering strong_ordering::less = {-1};
602 constexpr strong_ordering strong_ordering::equal = {0};
603 constexpr strong_ordering strong_ordering::greater = {1};
605 class partial_ordering {
606 public:
607 long n;
608 static const partial_ordering less, equal, greater, equivalent, unordered;
609 constexpr bool operator==(long n) const noexcept { return this->n == n;}
610 constexpr bool operator!=(long n) const noexcept { return this->n != n;}
612 constexpr partial_ordering partial_ordering::less = {-1};
613 constexpr partial_ordering partial_ordering::equal = {0};
614 constexpr partial_ordering partial_ordering::greater = {1};
615 constexpr partial_ordering partial_ordering::equivalent = {0};
616 constexpr partial_ordering partial_ordering::unordered = {-127};
617 } // namespace std
619 namespace ThreeWayCmp {
620 static_assert(1 <=> 2 == -1, "");
621 static_assert(1 <=> 1 == 0, "");
622 static_assert(2 <=> 1 == 1, "");
623 static_assert(1.0 <=> 2.f == -1, "");
624 static_assert(1.0 <=> 1.0 == 0, "");
625 static_assert(2.0 <=> 1.0 == 1, "");
626 constexpr int k = (1 <=> 1, 0); // both-warning {{comparison result unused}}
627 static_assert(k== 0, "");
629 /// Pointers.
630 constexpr int a[] = {1,2,3};
631 constexpr int b[] = {1,2,3};
632 constexpr const int *pa1 = &a[1];
633 constexpr const int *pa2 = &a[2];
634 constexpr const int *pb1 = &b[1];
635 static_assert(pa1 <=> pb1 != 0, ""); // both-error {{not an integral constant expression}} \
636 // both-note {{has unspecified value}}
637 static_assert(pa1 <=> pa1 == 0, "");
638 static_assert(pa1 <=> pa2 == -1, "");
639 static_assert(pa2 <=> pa1 == 1, "");
642 namespace ConstexprArrayInitLoopExprDestructors
644 struct Highlander {
645 int *p = 0;
646 constexpr Highlander() {}
647 constexpr void set(int *p) { this->p = p; ++*p; if (*p != 1) throw "there can be only one"; }
648 constexpr ~Highlander() { --*p; }
651 struct X {
652 int *p;
653 constexpr X(int *p) : p(p) {}
654 constexpr X(const X &x, Highlander &&h = Highlander()) : p(x.p) {
655 h.set(p);
659 constexpr int f() {
660 int n = 0;
661 X x[3] = {&n, &n, &n};
662 auto [a, b, c] = x;
663 return n;
666 static_assert(f() == 0);
669 namespace NonPrimitiveOpaqueValue
671 struct X {
672 int x;
673 constexpr operator bool() const { return x != 0; }
676 constexpr int ternary() { return X(0) ?: X(0); }
678 static_assert(!ternary(), "");
681 namespace TryCatch {
682 constexpr int foo() {
683 int a = 10;
684 try {
685 ++a;
686 } catch(int m) {
687 --a;
689 return a;
691 static_assert(foo() == 11);
694 namespace IgnoredConstantExpr {
695 consteval int immediate() { return 0;}
696 struct ReferenceToNestedMembers {
697 int m;
698 int a = ((void)immediate(), m);
699 int b = ((void)immediate(), this->m);
701 struct ReferenceToNestedMembersTest {
702 void* m = nullptr;
703 ReferenceToNestedMembers j{0};
704 } test_reference_to_nested_members;
707 namespace RewrittenBinaryOperators {
708 template <class T, T Val>
709 struct Conv {
710 constexpr operator T() const { return Val; }
711 operator T() { return Val; }
714 struct X {
715 constexpr const Conv<int, -1> operator<=>(X) { return {}; }
717 static_assert(X() < X(), "");
720 namespace GH61417 {
721 struct A {
722 unsigned x : 1;
723 unsigned : 0;
724 unsigned y : 1;
726 constexpr A() : x(0), y(0) {}
727 bool operator==(const A& rhs) const noexcept = default;
730 void f1() {
731 constexpr A a, b;
732 constexpr bool c = (a == b); // no diagnostic, we should not be comparing the
733 // unnamed bit-field which is indeterminate
736 void f2() {
737 A a, b;
738 bool c = (a == b); // no diagnostic nor crash during codegen attempting to
739 // access info for unnamed bit-field
743 namespace FailingDestructor {
744 struct D {
745 int n;
746 bool can_destroy;
748 constexpr ~D() {
749 if (!can_destroy)
750 throw "oh no";
753 template<D d>
754 void f() {} // both-note {{invalid explicitly-specified argument}}
756 void g() {
757 f<D{0, false}>(); // both-error {{no matching function}}
762 void overflowInSwitchCase(int n) {
763 switch (n) {
764 case (int)(float)1e300: // both-error {{constant expression}} \
765 // both-note {{value +Inf is outside the range of representable values of type 'int'}}
766 break;
770 namespace APValues {
771 int g;
772 struct A { union { int n, m; }; int *p; int A::*q; char buffer[32]; };
773 template<A a> constexpr const A &get = a;
774 constexpr const A &v = get<A{}>;
775 constexpr const A &w = get<A{1, &g, &A::n, "hello"}>;
778 namespace self_referencing {
779 struct S {
780 S* ptr = nullptr;
781 constexpr S(int i) : ptr(this) {
782 if (this == ptr && i)
783 ptr = nullptr;
785 constexpr ~S() {}
788 void test() {
789 S s(1);
793 namespace GH64949 {
794 struct f {
795 int g; // both-note {{subobject declared here}}
796 constexpr ~f() {}
799 class h {
800 public:
801 consteval h(char *) {}
802 f i;
805 void test() { h{nullptr}; } // both-error {{call to consteval function 'GH64949::h::h' is not a constant expression}} \
806 // both-note {{subobject 'g' is not initialized}} \
807 // both-warning {{expression result unused}}
810 /// This used to cause an assertion failure inside EvaluationResult::checkFullyInitialized.
811 namespace CheckingNullPtrForInitialization {
812 struct X {
813 consteval operator const char *() const {
814 return nullptr;
817 const char *f() {
818 constexpr X x;
819 return x;
823 namespace VariadicCallOperator {
824 class F {
825 public:
826 constexpr void operator()(int a, int b, ...) {}
828 constexpr int foo() {
829 F f;
831 f(1,2, 3);
832 return 1;
834 constexpr int A = foo();
837 namespace DefinitionLoc {
839 struct NonConstexprCopy {
840 constexpr NonConstexprCopy() = default;
841 NonConstexprCopy(const NonConstexprCopy &);
842 constexpr NonConstexprCopy(NonConstexprCopy &&) = default;
844 int n = 42;
847 NonConstexprCopy::NonConstexprCopy(const NonConstexprCopy &) = default; // both-note {{here}}
849 constexpr NonConstexprCopy ncc1 = NonConstexprCopy(NonConstexprCopy());
850 constexpr NonConstexprCopy ncc2 = ncc1; // both-error {{constant expression}} \
851 // both-note {{non-constexpr constructor}}
854 namespace VirtDtor {
855 class B {
856 public:
857 constexpr B(char *p) : p(p) {}
858 virtual constexpr ~B() {
859 *p = 'B';
860 ++p;
863 char *p;
866 class C : public B {
867 public:
868 constexpr C(char *p) : B(p) {}
869 virtual constexpr ~C() override {
870 *p = 'C';
871 ++p;
875 union U {
876 constexpr U(char *p) : c(p) {}
877 constexpr ~U() {}
879 C c;
882 constexpr int test(char a, char b) {
883 char buff[2] = {};
884 U u(buff);
886 /// U is a union, so it won't call the destructor of its fields.
887 /// We do this manually here. Explicitly calling ~C() here should
888 /// also call the destructor of the base classes however.
889 u.c.~C();
891 return buff[0] == a && buff[1] == b;
894 static_assert(test('C', 'B'));