summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp4
-rw-r--r--clang/test/Layout/ms-x86-pack-and-align.cpp55
2 files changed, 58 insertions, 1 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 3c91360fb61..b5ebbee83b5 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2613,8 +2613,10 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) {
// bytes (in both 32 and 64 bits modes) and always involves rounding up to
// the required alignment, we don't know why.
if ((PreviousBaseLayout && PreviousBaseLayout->hasZeroSizedSubObject() &&
- BaseLayout.leadsWithZeroSizedBase()) || HasVtordisp)
+ BaseLayout.leadsWithZeroSizedBase()) || HasVtordisp) {
Size = Size.RoundUpToAlignment(VtorDispAlignment) + VtorDispSize;
+ RequiredAlignment = VtorDispAlignment;
+ }
// Insert the virtual base.
ElementInfo Info = getAdjustedElementInfo(BaseLayout);
CharUnits BaseOffset = Size.RoundUpToAlignment(Info.Alignment);
diff --git a/clang/test/Layout/ms-x86-pack-and-align.cpp b/clang/test/Layout/ms-x86-pack-and-align.cpp
index be0499c2cbb..73984652aeb 100644
--- a/clang/test/Layout/ms-x86-pack-and-align.cpp
+++ b/clang/test/Layout/ms-x86-pack-and-align.cpp
@@ -544,6 +544,60 @@ struct RE {
// CHECK-X64-NEXT: | [sizeof=1029, align=1
// CHECK-X64-NEXT: | nvsize=1029, nvalign=1]
+struct NA {};
+struct NB {};
+#pragma pack(push, 1)
+struct NC : virtual NA, virtual NB {};
+#pragma pack(pop)
+struct ND : NC {};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct NA (empty)
+// CHECK-NEXT: | [sizeof=1, align=1
+// CHECK-NEXT: | nvsize=0, nvalign=1]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct NB (empty)
+// CHECK-NEXT: | [sizeof=1, align=1
+// CHECK-NEXT: | nvsize=0, nvalign=1]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct NC
+// CHECK-NEXT: 0 | (NC vbtable pointer)
+// CHECK-NEXT: 4 | struct NA (virtual base) (empty)
+// CHECK-NEXT: 8 | struct NB (virtual base) (empty)
+// CHECK-NEXT: | [sizeof=8, align=1
+// CHECK-NEXT: | nvsize=4, nvalign=1]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct ND
+// CHECK-NEXT: 0 | struct NC (base)
+// CHECK-NEXT: 0 | (NC vbtable pointer)
+// CHECK-NEXT: 4 | struct NA (virtual base) (empty)
+// CHECK-NEXT: 8 | struct NB (virtual base) (empty)
+// CHECK-NEXT: | [sizeof=8, align=4
+// CHECK-NEXT: | nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT: 0 | struct NA (empty)
+// CHECK-X64-NEXT: | [sizeof=1, align=1
+// CHECK-X64-NEXT: | nvsize=0, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT: 0 | struct NB (empty)
+// CHECK-X64-NEXT: | [sizeof=1, align=1
+// CHECK-X64-NEXT: | nvsize=0, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT: 0 | struct NC
+// CHECK-X64-NEXT: 0 | (NC vbtable pointer)
+// CHECK-X64-NEXT: 8 | struct NA (virtual base) (empty)
+// CHECK-X64-NEXT: 12 | struct NB (virtual base) (empty)
+// CHECK-X64-NEXT: | [sizeof=12, align=1
+// CHECK-X64-NEXT: | nvsize=8, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT: 0 | struct ND
+// CHECK-X64-NEXT: 0 | struct NC (base)
+// CHECK-X64-NEXT: 0 | (NC vbtable pointer)
+// CHECK-X64-NEXT: 8 | struct NA (virtual base) (empty)
+// CHECK-X64-NEXT: 12 | struct NB (virtual base) (empty)
+// CHECK-X64-NEXT: | [sizeof=12, align=4
+// CHECK-X64-NEXT: | nvsize=8, nvalign=4]
+
int a[
sizeof(X)+
sizeof(Y)+
@@ -568,4 +622,5 @@ sizeof(RB2)+
sizeof(RB3)+
sizeof(RC)+
sizeof(RE)+
+sizeof(ND)+
0];
OpenPOWER on IntegriCloud