]> granicus.if.org Git - clang/commitdiff
[ms-abi] Leading VFPtrs don't suppress the leading zero sized flag
authorWarren Hunt <whunt@google.com>
Mon, 13 Jan 2014 19:55:52 +0000 (19:55 +0000)
committerWarren Hunt <whunt@google.com>
Mon, 13 Jan 2014 19:55:52 +0000 (19:55 +0000)
The MS-ABI tracks a bit that asserts that the first sub-object is zero
sized.  This bit is used to add padding between objects if there's the
potential for zero sized objects to alias.  The bit is still true even
if the zero sized base is lead by a VFPtr.  This patch makes clang mimic
that behavior.

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

lib/AST/RecordLayoutBuilder.cpp
test/Layout/ms-x86-alias-avoidance-padding.cpp

index 885d4ff5fb6738a524c5b553762f51505d8070ed..e9289a0f055dcac953b1a9d2f888ee436951c5ea 100644 (file)
@@ -2302,8 +2302,10 @@ MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) {
     if (!BaseLayout.hasExtendableVFPtr())
       continue;
     // If we don't have a primary base, this one qualifies.
-    if (!PrimaryBase)
+    if (!PrimaryBase) {
       PrimaryBase = BaseDecl;
+      LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase();
+    }
     // Lay out the base.
     layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout);
   }
index 48249137017969f8c85af35221bc397c960bb29e..3112b39c9bc677c230171040893e535e789fee7a 100644 (file)
@@ -255,10 +255,54 @@ struct F : virtual D, virtual B {};
 // CHECK-X64-NEXT:      | [sizeof=32, align=8
 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
 
+struct JC0 {
+       JC0() { printf("JC0 : %d\n", (int)((char*)this - buffer)); }
+};
+struct JC1 : JC0 {
+       virtual void f() {}
+       JC1() { printf("JC1 : %d\n", (int)((char*)this - buffer)); }
+};
+struct JC2 : JC1 {
+       JC2() { printf("JC2 : %d\n", (int)((char*)this - buffer)); }
+};
+struct JC4 : JC1, JC2 {
+       JC4() { printf("JC4 : %d\n", (int)((char*)this - buffer)); }
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct JC4
+// CHECK-NEXT:    0 |   struct JC1 (primary base)
+// CHECK-NEXT:    0 |     (JC1 vftable pointer)
+// CHECK-NEXT:    4 |     struct JC0 (base) (empty)
+// CHECK-NEXT:    8 |   struct JC2 (base)
+// CHECK-NEXT:    8 |     struct JC1 (primary base)
+// CHECK-NEXT:    8 |       (JC1 vftable pointer)
+// CHECK-NEXT:   12 |       struct JC0 (base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
+// CHECK-x64: *** Dumping AST Record Layout
+// CHECK-x64: *** Dumping AST Record Layout
+// CHECK-x64: *** Dumping AST Record Layout
+// CHECK-x64: *** Dumping AST Record Layout
+// CHECK-x64-NEXT:    0 | struct JC4
+// CHECK-x64-NEXT:    0 |   struct JC1 (primary base)
+// CHECK-x64-NEXT:    0 |     (JC1 vftable pointer)
+// CHECK-x64-NEXT:    8 |     struct JC0 (base) (empty)
+// CHECK-x64-NEXT:   16 |   struct JC2 (base)
+// CHECK-x64-NEXT:   16 |     struct JC1 (primary base)
+// CHECK-x64-NEXT:   16 |       (JC1 vftable pointer)
+// CHECK-x64-NEXT:   24 |       struct JC0 (base) (empty)
+// CHECK-x64-NEXT:      | [sizeof=24, align=8
+// CHECK-x64-NEXT:      |  nvsize=24, nvalign=8]
+
 int a[
 sizeof(AT3) +
 sizeof(BT3) +
 sizeof(T3) +
 sizeof(E) +
 sizeof(F) +
+sizeof(JC4) +
 0];