From 6ab1e941149a0fe2688f7d2bdc458db2b641cdd3 Mon Sep 17 00:00:00 2001 From: Warren Hunt Date: Wed, 11 Dec 2013 02:21:03 +0000 Subject: [PATCH] [ms-abi] Makes Virtual Base Alignment Look at All Virtual Bases 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 | 13 ++++++++----- test/Layout/ms-x86-pack-and-align.cpp | 27 ++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index a5b07384dc..112e6d6981 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -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(i->getType()->getAs()->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 diff --git a/test/Layout/ms-x86-pack-and-align.cpp b/test/Layout/ms-x86-pack-and-align.cpp index f9f2b30f5f..c7bf4d3157 100644 --- a/test/Layout/ms-x86-pack-and-align.cpp +++ b/test/Layout/ms-x86-pack-and-align.cpp @@ -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)]; -- 2.40.0