Skip to content

Commit 3745f47

Browse files
authored
Fix to msvc::no_unique_address causing assert when used with __declspec(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
1 parent d96f46d commit 3745f47

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

clang/lib/AST/RecordLayoutBuilder.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2942,8 +2942,8 @@ void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
29422942
}
29432943

29442944
if (!FoundBase) {
2945-
if (MDCUsesEBO && BaseDecl->isEmpty()) {
2946-
assert(BaseLayout.getNonVirtualSize() == CharUnits::Zero());
2945+
if (MDCUsesEBO && BaseDecl->isEmpty() &&
2946+
(BaseLayout.getNonVirtualSize() == CharUnits::Zero())) {
29472947
BaseOffset = CharUnits::Zero();
29482948
} else {
29492949
// Otherwise, lay the base out at the end of the MDC.

clang/test/Layout/ms-x86-declspec-empty_bases.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,63 @@ int _ = sizeof(G);
264264
// CHECK-NEXT: | [sizeof=12, align=4,
265265
// CHECK-NEXT: | nvsize=12, nvalign=4]
266266
}
267+
268+
namespace test5 {
269+
270+
struct A {
271+
int a;
272+
};
273+
struct B {
274+
int b;
275+
};
276+
struct C {};
277+
struct __declspec(align(16)) D {};
278+
struct E {
279+
[[msvc::no_unique_address]] C c;
280+
};
281+
struct __declspec(empty_bases) X : A, D, B, C, E {
282+
};
283+
284+
// CHECK: *** Dumping AST Record Layout
285+
// CHECK-NEXT: 0 | struct test5::A
286+
// CHECK-NEXT: 0 | int a
287+
// CHECK-NEXT: | [sizeof=4, align=4,
288+
// CHECK-NEXT: | nvsize=4, nvalign=4]
289+
290+
// CHECK: *** Dumping AST Record Layout
291+
// CHECK-NEXT: 0 | struct test5::D (empty)
292+
// CHECK-NEXT: | [sizeof=16, align=16,
293+
// CHECK-NEXT: | nvsize=0, nvalign=16]
294+
295+
// CHECK: *** Dumping AST Record Layout
296+
// CHECK-NEXT: 0 | struct test5::B
297+
// CHECK-NEXT: 0 | int b
298+
// CHECK-NEXT: | [sizeof=4, align=4,
299+
// CHECK-NEXT: | nvsize=4, nvalign=4]
300+
301+
// CHECK: *** Dumping AST Record Layout
302+
// CHECK-NEXT: 0 | struct test5::C (empty)
303+
// CHECK-NEXT: | [sizeof=1, align=1,
304+
// CHECK-NEXT: | nvsize=0, nvalign=1]
305+
306+
// CHECK: *** Dumping AST Record Layout
307+
// CHECK-NEXT: 0 | struct test5::E (empty)
308+
// CHECK-NEXT: 0 | struct test5::C c (empty)
309+
// CHECK-NEXT: | [sizeof=1, align=1,
310+
// CHECK-NEXT: | nvsize=1, nvalign=1]
311+
312+
// CHECK: *** Dumping AST Record Layout
313+
// CHECK-NEXT: 0 | struct test5::X
314+
// CHECK-NEXT: 0 | struct test5::A (base)
315+
// CHECK-NEXT: 0 | int a
316+
// CHECK-NEXT: 0 | struct test5::D (base) (empty)
317+
// CHECK-NEXT: 0 | struct test5::C (base) (empty)
318+
// CHECK-NEXT: 4 | struct test5::B (base)
319+
// CHECK-NEXT: 4 | int b
320+
// CHECK-NEXT: 8 | struct test5::E (base) (empty)
321+
// CHECK-NEXT: 8 | struct test5::C c (empty)
322+
// CHECK-NEXT: | [sizeof=16, align=16,
323+
// CHECK-NEXT: | nvsize=16, nvalign=16]
324+
325+
int _ = sizeof(X);
326+
}

0 commit comments

Comments
 (0)