]> granicus.if.org Git - clang/commitdiff
[MS-ABI] adds padding before all vbases after a bitfield
authorWarren Hunt <whunt@google.com>
Fri, 6 Dec 2013 20:16:49 +0000 (20:16 +0000)
committerWarren Hunt <whunt@google.com>
Fri, 6 Dec 2013 20:16:49 +0000 (20:16 +0000)
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

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

lib/AST/RecordLayoutBuilder.cpp
test/Layout/ms-x86-bitfields-vbases.cpp

index ec79156489386899adf66503548f7364db26e20a..b692025aa0fdc07b9fa42ef6d372692a3bdbfea3 100644 (file)
@@ -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));
   }
 }
index e11ef67a63477ebc361af08c68b151374ab59213..f973edd6a3e54621f2dc5a77288e6e8291313caa 100644 (file)
 // 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 { };\r
-\r
-struct A : virtual B0 { char a : 1; };\r
+struct B0 { int a; };
+struct B1 { int a; };
 
-// CHECK: *** Dumping AST Record Layout\r
-// CHECK:    0 | struct A\r
-// CHECK:    0 |   (A vbtable pointer)\r
-// CHECK:    4 |   char a\r
-// CHECK:    9 |   struct B0 (virtual base) (empty)\r
-// CHECK:      | [sizeof=9, align=4\r
-// CHECK:      |  nvsize=8, nvalign=4]\r
+struct A : virtual B0 { char a : 1; };
+
+// CHECK: *** Dumping AST Record Layout
+// 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 A\r
-// CHECK-X64:    0 |   (A vbtable pointer)\r
-// CHECK-X64:    8 |   char a\r
-// CHECK-X64:   17 |   struct B0 (virtual base) (empty)\r
-// CHECK-X64:      | [sizeof=24, align=8\r
-// CHECK-X64:      |  nvsize=16, nvalign=8]\r
+// 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 B : virtual B0 { short a : 1; };\r
+struct B : virtual B0 { short a : 1; };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B\r
-// CHECK:    0 |   (B vbtable pointer)\r
-// CHECK:    4 |   short a\r
-// CHECK:   10 |   struct B0 (virtual base) (empty)\r
-// CHECK:      | [sizeof=10, align=4\r
-// CHECK:      |  nvsize=8, nvalign=4]\r
+// 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 B\r
-// CHECK-X64:    0 |   (B vbtable pointer)\r
-// CHECK-X64:    8 |   short a\r
-// CHECK-X64:   18 |   struct B0 (virtual base) (empty)\r
-// CHECK-X64:      | [sizeof=24, align=8\r
-// CHECK-X64:      |  nvsize=16, nvalign=8]\r
+// 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 C : virtual B0 { char a : 1; char : 0; };\r
+struct C : virtual B0 { char a : 1; char : 0; };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C\r
-// CHECK:    0 |   (C vbtable pointer)\r
-// CHECK:    4 |   char a\r
-// CHECK:    5 |   char\r
-// CHECK:    8 |   struct B0 (virtual base) (empty)\r
-// CHECK:      | [sizeof=8, align=4\r
-// CHECK:      |  nvsize=8, nvalign=4]\r
+// 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 C\r
-// CHECK-X64:    0 |   (C vbtable pointer)\r
-// CHECK-X64:    8 |   char a\r
-// CHECK-X64:    9 |   char\r
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)\r
-// CHECK-X64:      | [sizeof=16, align=8\r
-// CHECK-X64:      |  nvsize=16, nvalign=8]\r
+// 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; };
 
-struct D : virtual B0 { char a : 1; char b; };\r
+// 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 D\r
-// CHECK:    0 |   (D vbtable pointer)\r
-// CHECK:    4 |   char a\r
-// CHECK:    5 |   char b\r
-// CHECK:    8 |   struct B0 (virtual base) (empty)\r
-// CHECK:      | [sizeof=8, align=4\r
-// CHECK:      |  nvsize=8, nvalign=4]\r
+// 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 D\r
-// CHECK-X64:    0 |   (D vbtable pointer)\r
-// CHECK-X64:    8 |   char a\r
-// CHECK-X64:    9 |   char b\r
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)\r
-// CHECK-X64:      | [sizeof=16, align=8\r
-// CHECK-X64:      |  nvsize=16, nvalign=8]\r
+// 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)];