]> granicus.if.org Git - clang/commitdiff
[ms-abi] Makes Virtual Base Alignment Look at All Virtual Bases
authorWarren Hunt <whunt@google.com>
Wed, 11 Dec 2013 02:21:03 +0000 (02:21 +0000)
committerWarren Hunt <whunt@google.com>
Wed, 11 Dec 2013 02:21:03 +0000 (02:21 +0000)
Prior to this patch, the alignment imposed by virtual bases only
included direct virtual bases.  This patch fixes it to look at all
virtual bases.

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

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

index a5b07384dc8d45c8b9f279a87e63dcb5963dc4c8..112e6d6981d5375d857a87fa00c389328eab31be 100644 (file)
@@ -2125,8 +2125,6 @@ public:
   /// \brief The alignment of the non-virtual portion of the record layout
   /// Only used for C++ layouts.
   CharUnits NonVirtualAlignment;
-  /// \brief The additional alignment imposed by the virtual bases.
-  CharUnits VirtualAlignment;
   /// \brief The primary base class (if one exists).
   const CXXRecordDecl *PrimaryBase;
   /// \brief The class we share our vb-pointer with.
@@ -2265,7 +2263,6 @@ MicrosoftRecordLayoutBuilder::initializeCXXLayout(const CXXRecordDecl *RD) {
   HasExtendableVFPtr = false;
   SharedVBPtrBase = 0;
   PrimaryBase = 0;
-  VirtualAlignment = CharUnits::One();
   LeadsWithZeroSizedBase = false;
 
   // If the record has a dynamic base class, attempt to choose a primary base
@@ -2285,7 +2282,6 @@ MicrosoftRecordLayoutBuilder::initializeCXXLayout(const CXXRecordDecl *RD) {
       HasZeroSizedSubObject = true;
     // Handle virtual bases.
     if (i->isVirtual()) {
-      VirtualAlignment = std::max(VirtualAlignment, getBaseAlignment(Layout));
       HasVBPtr = true;
       continue;
     }
@@ -2555,7 +2551,14 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) {
   if (!HasVBPtr)
     return;
 
-  updateAlignment(VirtualAlignment);
+  for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
+                                                e = RD->vbases_end();
+       i != e; ++i) {
+    const CXXRecordDecl *BaseDecl =
+        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
+    updateAlignment(getBaseAlignment(Layout));
+  }
   PreviousBaseLayout = 0;
 
   // Zero-sized v-bases obey the alignment attribute so apply it here.  The
index f9f2b30f5f73e006aa18b040392f51a0442ee572..c7bf4d31579bc46add84e160fb7938987a43703b 100644 (file)
@@ -114,7 +114,32 @@ struct Z : virtual B {
 
 #pragma pack(pop)
 
+struct A1 { long long a; };
+#pragma pack(push, 1)
+struct B1 : virtual A1 { char a; };
+#pragma pack(pop)
+struct C1 : B1 {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK:    0 | struct C1
+// CHECK:    0 |   struct B1 (base)
+// CHECK:    0 |     (B1 vbtable pointer)
+// CHECK:    4 |     char a
+// CHECK:    8 |   struct A1 (virtual base)
+// CHECK:    8 |     long long a
+// CHECK:      | [sizeof=16, align=8
+// CHECK:      |  nvsize=5, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64:    0 | struct C1
+// CHECK-X64:    0 |   struct B1 (base)
+// CHECK-X64:    0 |     (B1 vbtable pointer)
+// CHECK-X64:    8 |     char a
+// CHECK-X64:   16 |   struct A1 (virtual base)
+// CHECK-X64:   16 |     long long a
+// CHECK-X64:      | [sizeof=24, align=8
+// CHECK-X64:      |  nvsize=9, nvalign=1]
+
 int a[
 sizeof(X)+
 sizeof(Y)+
-sizeof(Z)];
+sizeof(Z)+
+sizeof(C1)];