[clang] Fix to msvc::no_unique_address causing assert when used with __declspec(empty_bases) (PR #74776)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 7 14:45:56 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Amy Huang (amykhuang)
<details>
<summary>Changes</summary>
no_unique_address makes it possible for a class to be empty and have non-zero virtual size, so just remove this assert.
Bug: https://github.com/llvm/llvm-project/issues/74442
---
Full diff: https://github.com/llvm/llvm-project/pull/74776.diff
2 Files Affected:
- (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+2-2)
- (modified) clang/test/Layout/ms-x86-declspec-empty_bases.cpp (+60)
``````````diff
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index f1f2275da44dc..73b248ffe5899 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2936,8 +2936,8 @@ void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
}
if (!FoundBase) {
- if (MDCUsesEBO && BaseDecl->isEmpty()) {
- assert(BaseLayout.getNonVirtualSize() == CharUnits::Zero());
+ if (MDCUsesEBO && BaseDecl->isEmpty() &&
+ (BaseLayout.getNonVirtualSize() == CharUnits::Zero())) {
BaseOffset = CharUnits::Zero();
} else {
// Otherwise, lay the base out at the end of the MDC.
diff --git a/clang/test/Layout/ms-x86-declspec-empty_bases.cpp b/clang/test/Layout/ms-x86-declspec-empty_bases.cpp
index cc13a980cb5db..4738ce5720f75 100644
--- a/clang/test/Layout/ms-x86-declspec-empty_bases.cpp
+++ b/clang/test/Layout/ms-x86-declspec-empty_bases.cpp
@@ -264,3 +264,63 @@ int _ = sizeof(G);
// CHECK-NEXT: | [sizeof=12, align=4,
// CHECK-NEXT: | nvsize=12, nvalign=4]
}
+
+namespace test5 {
+
+struct A {
+ int a;
+};
+struct B {
+ int b;
+};
+struct C {};
+struct __declspec(align(16)) D {};
+struct E {
+ [[msvc::no_unique_address]] C c;
+};
+struct __declspec(empty_bases) X : A, D, B, C, E {
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test5::A
+// CHECK-NEXT: 0 | int a
+// CHECK-NEXT: | [sizeof=4, align=4,
+// CHECK-NEXT: | nvsize=4, nvalign=4]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test5::D (empty)
+// CHECK-NEXT: | [sizeof=16, align=16,
+// CHECK-NEXT: | nvsize=0, nvalign=16]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test5::B
+// CHECK-NEXT: 0 | int b
+// CHECK-NEXT: | [sizeof=4, align=4,
+// CHECK-NEXT: | nvsize=4, nvalign=4]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test5::C (empty)
+// CHECK-NEXT: | [sizeof=1, align=1,
+// CHECK-NEXT: | nvsize=0, nvalign=1]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test5::E (empty)
+// CHECK-NEXT: 0 | struct test5::C c (empty)
+// CHECK-NEXT: | [sizeof=1, align=1,
+// CHECK-NEXT: | nvsize=1, nvalign=1]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test5::X
+// CHECK-NEXT: 0 | struct test5::A (base)
+// CHECK-NEXT: 0 | int a
+// CHECK-NEXT: 0 | struct test5::D (base) (empty)
+// CHECK-NEXT: 0 | struct test5::C (base) (empty)
+// CHECK-NEXT: 4 | struct test5::B (base)
+// CHECK-NEXT: 4 | int b
+// CHECK-NEXT: 8 | struct test5::E (base) (empty)
+// CHECK-NEXT: 8 | struct test5::C c (empty)
+// CHECK-NEXT: | [sizeof=16, align=16,
+// CHECK-NEXT: | nvsize=16, nvalign=16]
+
+int _ = sizeof(X);
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/74776
More information about the cfe-commits
mailing list