forked from OSchip/llvm-project
[MS-ABI] adds padding before all vbases after a bitfield
MS-ABI adds padding before *every* vbase if the last field in a record is a bit-field. This changes clangs behavior to match. I also fix some windows-style line endings in the test file. Differential Revision: http://llvm-reviews.chandlerc.com/D2277 llvm-svn: 196605
This commit is contained in:
parent
1a68f2383f
commit
71140d68f8
|
@ -2014,9 +2014,9 @@ static bool isMsLayout(const RecordDecl* D) {
|
|||
// one.
|
||||
// * The last zero size virtual base may be placed at the end of the struct.
|
||||
// and can potentially alias a zero sized type in the next struct.
|
||||
// * If the last field is a non-zero length bitfield and we have any virtual
|
||||
// bases then some extra padding is added before the virtual bases for no
|
||||
// obvious reason.
|
||||
// * If the last field is a non-zero length bitfield, all virtual bases will
|
||||
// have extra padding added before them for no obvious reason. The padding
|
||||
// has the same number of bits as the type of the bitfield.
|
||||
// * When laying out empty non-virtual bases, an extra byte of padding is added
|
||||
// if the non-virtual base before the empty non-virtual base has a vbptr.
|
||||
// * The ABI attempts to avoid aliasing of zero sized bases by adding padding
|
||||
|
@ -2558,17 +2558,16 @@ void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) {
|
|||
llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordisp =
|
||||
computeVtorDispSet(RD);
|
||||
|
||||
// If the last field we laid out was a non-zero length bitfield then add some
|
||||
// extra padding for no obvious reason.
|
||||
if (LastFieldIsNonZeroWidthBitfield)
|
||||
Size += CurrentBitfieldSize;
|
||||
|
||||
// Iterate through the virtual bases and lay them out.
|
||||
for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
|
||||
e = RD->vbases_end();
|
||||
i != e; ++i) {
|
||||
const CXXRecordDecl *BaseDecl =
|
||||
cast<CXXRecordDecl>(i->getType()->castAs<RecordType>()->getDecl());
|
||||
// If the last field we laid out was a non-zero length bitfield then add
|
||||
// some extra padding for no obvious reason.
|
||||
if (LastFieldIsNonZeroWidthBitfield)
|
||||
Size += CurrentBitfieldSize;
|
||||
layoutVirtualBase(BaseDecl, HasVtordisp.count(BaseDecl));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,82 +3,114 @@
|
|||
// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
|
||||
// RUN: | FileCheck %s -check-prefix CHECK-X64
|
||||
|
||||
struct B0 { };
|
||||
|
||||
struct A : virtual B0 { char a : 1; };
|
||||
struct B0 { int a; };
|
||||
struct B1 { int a; };
|
||||
|
||||
// CHECK: *** Dumping AST Record Layout
|
||||
// CHECK: 0 | struct A
|
||||
// CHECK: 0 | (A vbtable pointer)
|
||||
// CHECK: 4 | char a
|
||||
// CHECK: 9 | struct B0 (virtual base) (empty)
|
||||
// CHECK: | [sizeof=9, align=4
|
||||
// CHECK: | nvsize=8, nvalign=4]
|
||||
// CHECK-X64: *** Dumping AST Record Layout
|
||||
// CHECK-X64: 0 | struct A
|
||||
// CHECK-X64: 0 | (A vbtable pointer)
|
||||
// CHECK-X64: 8 | char a
|
||||
// CHECK-X64: 17 | struct B0 (virtual base) (empty)
|
||||
// CHECK-X64: | [sizeof=24, align=8
|
||||
// CHECK-X64: | nvsize=16, nvalign=8]
|
||||
|
||||
struct B : virtual B0 { short a : 1; };
|
||||
struct A : virtual B0 { char a : 1; };
|
||||
|
||||
// CHECK: *** Dumping AST Record Layout
|
||||
// CHECK: 0 | struct B
|
||||
// CHECK: 0 | (B vbtable pointer)
|
||||
// CHECK: 4 | short a
|
||||
// CHECK: 10 | struct B0 (virtual base) (empty)
|
||||
// CHECK: | [sizeof=10, align=4
|
||||
// CHECK: | nvsize=8, nvalign=4]
|
||||
// CHECK: 0 | struct A
|
||||
// CHECK: 0 | (A vbtable pointer)
|
||||
// CHECK: 4 | char a
|
||||
// CHECK: 12 | struct B0 (virtual base)
|
||||
// CHECK: 12 | int a
|
||||
// CHECK: | [sizeof=16, align=4
|
||||
// CHECK: | nvsize=8, nvalign=4]
|
||||
// CHECK-X64: *** Dumping AST Record Layout
|
||||
// CHECK-X64: 0 | struct B
|
||||
// CHECK-X64: 0 | (B vbtable pointer)
|
||||
// CHECK-X64: 8 | short a
|
||||
// CHECK-X64: 18 | struct B0 (virtual base) (empty)
|
||||
// CHECK-X64: | [sizeof=24, align=8
|
||||
// CHECK-X64: | nvsize=16, nvalign=8]
|
||||
// CHECK-X64: 0 | struct A
|
||||
// CHECK-X64: 0 | (A vbtable pointer)
|
||||
// CHECK-X64: 8 | char a
|
||||
// CHECK-X64: 20 | struct B0 (virtual base)
|
||||
// CHECK-X64: 20 | int a
|
||||
// CHECK-X64: | [sizeof=24, align=8
|
||||
// CHECK-X64: | nvsize=16, nvalign=8]
|
||||
|
||||
struct C : virtual B0 { char a : 1; char : 0; };
|
||||
struct B : virtual B0 { short a : 1; };
|
||||
|
||||
// CHECK: *** Dumping AST Record Layout
|
||||
// CHECK: 0 | struct C
|
||||
// CHECK: 0 | (C vbtable pointer)
|
||||
// CHECK: 4 | char a
|
||||
// CHECK: 5 | char
|
||||
// CHECK: 8 | struct B0 (virtual base) (empty)
|
||||
// CHECK: | [sizeof=8, align=4
|
||||
// CHECK: | nvsize=8, nvalign=4]
|
||||
// CHECK: 0 | struct B
|
||||
// CHECK: 0 | (B vbtable pointer)
|
||||
// CHECK: 4 | short a
|
||||
// CHECK: 12 | struct B0 (virtual base)
|
||||
// CHECK: 12 | int a
|
||||
// CHECK: | [sizeof=16, align=4
|
||||
// CHECK: | nvsize=8, nvalign=4]
|
||||
// CHECK-X64: *** Dumping AST Record Layout
|
||||
// CHECK-X64: 0 | struct C
|
||||
// CHECK-X64: 0 | (C vbtable pointer)
|
||||
// CHECK-X64: 8 | char a
|
||||
// CHECK-X64: 9 | char
|
||||
// CHECK-X64: 16 | struct B0 (virtual base) (empty)
|
||||
// CHECK-X64: | [sizeof=16, align=8
|
||||
// CHECK-X64: | nvsize=16, nvalign=8]
|
||||
// CHECK-X64: 0 | struct B
|
||||
// CHECK-X64: 0 | (B vbtable pointer)
|
||||
// CHECK-X64: 8 | short a
|
||||
// CHECK-X64: 20 | struct B0 (virtual base)
|
||||
// CHECK-X64: 20 | int a
|
||||
// CHECK-X64: | [sizeof=24, align=8
|
||||
// CHECK-X64: | nvsize=16, nvalign=8]
|
||||
|
||||
struct D : virtual B0 { char a : 1; char b; };
|
||||
struct C : virtual B0 { char a : 1; char : 0; };
|
||||
|
||||
// CHECK: *** Dumping AST Record Layout
|
||||
// CHECK: 0 | struct D
|
||||
// CHECK: 0 | (D vbtable pointer)
|
||||
// CHECK: 4 | char a
|
||||
// CHECK: 5 | char b
|
||||
// CHECK: 8 | struct B0 (virtual base) (empty)
|
||||
// CHECK: | [sizeof=8, align=4
|
||||
// CHECK: | nvsize=8, nvalign=4]
|
||||
// CHECK: 0 | struct C
|
||||
// CHECK: 0 | (C vbtable pointer)
|
||||
// CHECK: 4 | char a
|
||||
// CHECK: 5 | char
|
||||
// CHECK: 8 | struct B0 (virtual base)
|
||||
// CHECK: 8 | int a
|
||||
// CHECK: | [sizeof=12, align=4
|
||||
// CHECK: | nvsize=8, nvalign=4]
|
||||
// CHECK-X64: *** Dumping AST Record Layout
|
||||
// CHECK-X64: 0 | struct D
|
||||
// CHECK-X64: 0 | (D vbtable pointer)
|
||||
// CHECK-X64: 8 | char a
|
||||
// CHECK-X64: 9 | char b
|
||||
// CHECK-X64: 16 | struct B0 (virtual base) (empty)
|
||||
// CHECK-X64: | [sizeof=16, align=8
|
||||
// CHECK-X64: | nvsize=16, nvalign=8]
|
||||
// CHECK-X64: 0 | struct C
|
||||
// CHECK-X64: 0 | (C vbtable pointer)
|
||||
// CHECK-X64: 8 | char a
|
||||
// CHECK-X64: 9 | char
|
||||
// CHECK-X64: 16 | struct B0 (virtual base)
|
||||
// CHECK-X64: 16 | int a
|
||||
// CHECK-X64: | [sizeof=24, align=8
|
||||
// CHECK-X64: | nvsize=16, nvalign=8]
|
||||
|
||||
struct D : virtual B0 { char a : 1; char b; };
|
||||
|
||||
// CHECK: *** Dumping AST Record Layout
|
||||
// CHECK: 0 | struct D
|
||||
// CHECK: 0 | (D vbtable pointer)
|
||||
// CHECK: 4 | char a
|
||||
// CHECK: 5 | char b
|
||||
// CHECK: 8 | struct B0 (virtual base)
|
||||
// CHECK: 8 | int a
|
||||
// CHECK: | [sizeof=12, align=4
|
||||
// CHECK: | nvsize=8, nvalign=4]
|
||||
// CHECK-X64: *** Dumping AST Record Layout
|
||||
// CHECK-X64: 0 | struct D
|
||||
// CHECK-X64: 0 | (D vbtable pointer)
|
||||
// CHECK-X64: 8 | char a
|
||||
// CHECK-X64: 9 | char b
|
||||
// CHECK-X64: 16 | struct B0 (virtual base)
|
||||
// CHECK-X64: 16 | int a
|
||||
// CHECK-X64: | [sizeof=24, align=8
|
||||
// CHECK-X64: | nvsize=16, nvalign=8]
|
||||
|
||||
struct E : virtual B0, virtual B1 { long long : 1; };
|
||||
// CHECK: *** Dumping AST Record Layout
|
||||
// CHECK: 0 | struct E
|
||||
// CHECK: 0 | (E vbtable pointer)
|
||||
// CHECK: 8 | long long
|
||||
// CHECK: 24 | struct B0 (virtual base)
|
||||
// CHECK: 24 | int a
|
||||
// CHECK: 36 | struct B1 (virtual base)
|
||||
// CHECK: 36 | int a
|
||||
// CHECK: | [sizeof=40, align=8
|
||||
// CHECK: | nvsize=16, nvalign=8]
|
||||
// CHECK-X64: *** Dumping AST Record Layout
|
||||
// CHECK-X64: 0 | struct E
|
||||
// CHECK-X64: 0 | (E vbtable pointer)
|
||||
// CHECK-X64: 8 | long long
|
||||
// CHECK-X64: 24 | struct B0 (virtual base)
|
||||
// CHECK-X64: 24 | int a
|
||||
// CHECK-X64: 36 | struct B1 (virtual base)
|
||||
// CHECK-X64: 36 | int a
|
||||
// CHECK-X64: | [sizeof=40, align=8
|
||||
// CHECK-X64: | nvsize=16, nvalign=8]
|
||||
|
||||
int a[
|
||||
sizeof(A)+
|
||||
sizeof(B)+
|
||||
sizeof(C)+
|
||||
sizeof(D)];
|
||||
sizeof(D)+
|
||||
sizeof(E)];
|
||||
|
|
Loading…
Reference in New Issue