]> granicus.if.org Git - clang/commitdiff
MS ABI: Up the required alignment after inserting padding between vbases
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 16 Jul 2014 07:16:58 +0000 (07:16 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 16 Jul 2014 07:16:58 +0000 (07:16 +0000)
We would correctly insert sufficiently aligned padding between vbases
when our leading base was empty, however we would neglect to increase
the required alignment of the most derived class.

This fixes PR20315.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213123 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/RecordLayoutBuilder.cpp
test/Layout/ms-x86-pack-and-align.cpp

index 3c91360fb61d9d7b102efcad18adde5b7438cc8a..b5ebbee83b5c6a0e8c41ed656e54c8ed5bc5e1a3 100644 (file)
@@ -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);
index be0499c2cbbeb210db446c3d68c2f3c950d8b327..73984652aeb202465336b5309d2cf0392d30c2a0 100644 (file)
@@ -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];