[clang] fe59b84 - [clang][Interp] Propagate InUnion flag to base classes (#102804)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 11 09:16:06 PDT 2024
Author: Timm Baeder
Date: 2024-08-11T18:16:03+02:00
New Revision: fe59b84f27181ef96fdf0f234a15f19d0a13a5c2
URL: https://github.com/llvm/llvm-project/commit/fe59b84f27181ef96fdf0f234a15f19d0a13a5c2
DIFF: https://github.com/llvm/llvm-project/commit/fe59b84f27181ef96fdf0f234a15f19d0a13a5c2.diff
LOG: [clang][Interp] Propagate InUnion flag to base classes (#102804)
Added:
Modified:
clang/lib/AST/Interp/Descriptor.cpp
clang/test/AST/Interp/unions.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Descriptor.cpp b/clang/lib/AST/Interp/Descriptor.cpp
index 634413b2f2f52..1b7d9f03f8ef0 100644
--- a/clang/lib/AST/Interp/Descriptor.cpp
+++ b/clang/lib/AST/Interp/Descriptor.cpp
@@ -171,30 +171,31 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
unsigned FieldOffset, bool IsVirtualBase) {
assert(D);
assert(D->ElemRecord);
+ assert(!D->ElemRecord->isUnion()); // Unions cannot be base classes.
- bool IsUnion = D->ElemRecord->isUnion();
auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + FieldOffset) - 1;
Desc->Offset = FieldOffset;
Desc->Desc = D;
Desc->IsInitialized = D->IsArray;
Desc->IsBase = true;
Desc->IsVirtualBase = IsVirtualBase;
- Desc->IsActive = IsActive && !IsUnion;
+ Desc->IsActive = IsActive && !InUnion;
Desc->IsConst = IsConst || D->IsConst;
Desc->IsFieldMutable = IsMutable || D->IsMutable;
+ Desc->InUnion = InUnion;
for (const auto &V : D->ElemRecord->bases())
initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
V.Desc, V.Offset, false);
for (const auto &F : D->ElemRecord->fields())
initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, InUnion,
- IsUnion, F.Desc, F.Offset);
+ InUnion, F.Desc, F.Offset);
}
static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, bool InUnion, const Descriptor *D) {
for (const auto &V : D->ElemRecord->bases())
- initBase(B, Ptr, IsConst, IsMutable, IsActive, false, V.Desc, V.Offset,
+ initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion, V.Desc, V.Offset,
false);
for (const auto &F : D->ElemRecord->fields()) {
bool IsUnionField = D->isUnion();
@@ -202,7 +203,7 @@ static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
InUnion || IsUnionField, F.Desc, F.Offset);
}
for (const auto &V : D->ElemRecord->virtual_bases())
- initBase(B, Ptr, IsConst, IsMutable, IsActive, false, V.Desc, V.Offset,
+ initBase(B, Ptr, IsConst, IsMutable, IsActive, InUnion, V.Desc, V.Offset,
true);
}
diff --git a/clang/test/AST/Interp/unions.cpp b/clang/test/AST/Interp/unions.cpp
index 4c60c2c0810d4..996d29e143fe2 100644
--- a/clang/test/AST/Interp/unions.cpp
+++ b/clang/test/AST/Interp/unions.cpp
@@ -358,4 +358,27 @@ namespace CopyCtor {
static_assert(y.b == 42, ""); // both-error {{constant expression}} \
// both-note {{'b' of union with active member 'a'}}
}
+
+namespace UnionInBase {
+ struct Base {
+ int y;
+ };
+ struct A : Base {
+ int x;
+ int arr[3];
+ union { int p, q; };
+ };
+ union B {
+ A a;
+ int b;
+ };
+ constexpr int read_wrong_member_indirect() { // both-error {{never produces a constant}}
+ B b = {.b = 1};
+ int *p = &b.a.y;
+ return *p; // both-note 2{{read of member 'a' of union with active member 'b'}}
+
+ }
+ static_assert(read_wrong_member_indirect() == 1); // both-error {{not an integral constant expression}} \
+ // both-note {{in call to}}
+}
#endif
More information about the cfe-commits
mailing list