diff options
Diffstat (limited to 'clang/test/AST')
-rw-r--r-- | clang/test/AST/ByteCode/builtin-bit-cast.cpp | 4 | ||||
-rw-r--r-- | clang/test/AST/ByteCode/unions.cpp | 72 | ||||
-rw-r--r-- | clang/test/AST/ast-dump-APValue-lvalue.cpp | 8 |
3 files changed, 79 insertions, 5 deletions
diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp index 3c5e89d7..bc356b0 100644 --- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp +++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp @@ -22,6 +22,10 @@ typedef __INTPTR_TYPE__ intptr_t; static_assert(sizeof(int) == 4); static_assert(sizeof(long long) == 8); + +constexpr bool test_bad_bool = __builtin_bit_cast(bool, (char)0xff); // both-error {{must be initialized by a constant expression}} \ + // both-note {{value 255 cannot be represented in type 'bool'}} + template <class To, class From> constexpr To bit_cast(const From &from) { static_assert(sizeof(To) == sizeof(From)); diff --git a/clang/test/AST/ByteCode/unions.cpp b/clang/test/AST/ByteCode/unions.cpp index 7cfd0d6..139e318 100644 --- a/clang/test/AST/ByteCode/unions.cpp +++ b/clang/test/AST/ByteCode/unions.cpp @@ -79,10 +79,9 @@ namespace DefaultInit { constexpr U1 u1; /// OK. - constexpr int foo() { // expected-error {{never produces a constant expression}} + constexpr int foo() { U1 u; - return u.a; // both-note {{read of member 'a' of union with active member 'b'}} \ - // expected-note {{read of member 'a' of union with active member 'b'}} + return u.a; // both-note {{read of member 'a' of union with active member 'b'}} } static_assert(foo() == 42); // both-error {{not an integral constant expression}} \ // both-note {{in call to}} @@ -861,6 +860,73 @@ namespace CopyCtorMutable { // both-note {{in call}} } + +namespace NonTrivialCtor { + struct A { int x = 1; constexpr int f() { return 1; } }; + struct B : A { int y = 1; constexpr int g() { return 2; } }; + struct C { + int x; + constexpr virtual int f() = 0; + }; + struct D : C { + int y; + constexpr virtual int f() override { return 3; } + }; + + union U { + int n; + B b; + D d; + }; + + consteval int test(int which) { + if (which == 0) {} + + U u{.n = 5}; + assert_active(u); + assert_active(u.n); + assert_inactive(u.b); + + switch (which) { + case 0: + u.b.x = 10; // both-note {{assignment to member 'b' of union with active member 'n'}} + return u.b.f(); + case 1: + u.b.y = 10; // both-note {{assignment to member 'b' of union with active member 'n'}} + return u.b.g(); + case 2: + u.d.x = 10; // both-note {{assignment to member 'd' of union with active member 'n'}} + return u.d.f(); + case 3: + u.d.y = 10; // both-note {{assignment to member 'd' of union with active member 'n'}} + return u.d.f(); + } + + return 1; + } + static_assert(test(0)); // both-error {{not an integral constant expression}} \ + // both-note {{in call}} + static_assert(test(1)); // both-error {{not an integral constant expression}} \ + // both-note {{in call}} + static_assert(test(2)); // both-error {{not an integral constant expression}} \ + // both-note {{in call}} + static_assert(test(3)); // both-error {{not an integral constant expression}} \ + // both-note {{in call}} + +} + +namespace PrimitiveFieldInitActivates { + /// The initializer of a needs the field to be active _before_ it's visited. + template<int> struct X {}; + union V { + int a, b; + constexpr V(X<0>) : a(a = 1) {} // ok + constexpr V(X<2>) : a() { b = 1; } // ok + }; + constinit V v0 = X<0>(); + constinit V v2 = X<2>(); +} + #endif namespace AddressComparison { diff --git a/clang/test/AST/ast-dump-APValue-lvalue.cpp b/clang/test/AST/ast-dump-APValue-lvalue.cpp index 51d22a5..f4cf2f5 100644 --- a/clang/test/AST/ast-dump-APValue-lvalue.cpp +++ b/clang/test/AST/ast-dump-APValue-lvalue.cpp @@ -67,6 +67,10 @@ void Test(int (&arr)[10]) { // CHECK-NEXT: | |-value: LValue Base=TypeInfoLValue typeid(int), Null=0, Offset=0, HasPath=1, PathLength=0, Path=() constexpr int(MP::*pmi) = (int MP::*)&P::x; - // CHECK: `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pmi 'int (MP::*const)' constexpr cinit - // CHECK-NEXT: |-value: MemberPointer MP::x + // CHECK: | `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pmi 'int (MP::*const)' constexpr cinit + // CHECK-NEXT: | |-value: MemberPointer MP::x + + constexpr int(MP::*pmn) = (int MP::*)nullptr; + // CHECK: `-VarDecl {{.*}} <col:{{.*}}, col:{{.*}}> col:{{.*}} pmn 'int (MP::*const)' constexpr cinit + // CHECK-NEXT: |-value: MemberPointer null } |