Skip to content

Commit

Permalink
Fix to msvc::no_unique_address causing assert when used with __declsp…
Browse files Browse the repository at this point in the history
…ec(empty_bases) (llvm#74776)

no_unique_address makes it possible for a class to be empty and have
non-zero virtual size, so just remove this assert.

Bug: llvm#74442
  • Loading branch information
amykhuang authored Dec 11, 2023
1 parent d96f46d commit 3745f47
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
4 changes: 2 additions & 2 deletions clang/lib/AST/RecordLayoutBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2942,8 +2942,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.
Expand Down
60 changes: 60 additions & 0 deletions clang/test/Layout/ms-x86-declspec-empty_bases.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 3745f47

Please sign in to comment.