r198059 - [ms-abi] Fixes improperly sized vfptrs with pragma pack

Warren Hunt whunt at google.com
Thu Dec 26 14:09:12 PST 2013


Author: whunt
Date: Thu Dec 26 16:09:12 2013
New Revision: 198059

URL: http://llvm.org/viewvc/llvm-project?rev=198059&view=rev
Log:
[ms-abi] Fixes improperly sized vfptrs with pragma pack

With pragma pack, the layout engine would produce vfptrs that were 
packed width rather than pointer width.  This patch addresses the issue 
and adds a test case.


Modified:
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=198059&r1=198058&r2=198059&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Thu Dec 26 16:09:12 2013
@@ -2316,15 +2316,14 @@ void MicrosoftRecordLayoutBuilder::layou
   if (!HasExtendableVFPtr)
     return;
 
+  updateAlignment(PointerAlignment);
+  Size = Size.RoundUpToAlignment(PointerAlignment) + PointerSize;
   // MSVC 32 (but not 64) potentially over-aligns the vf-table pointer by giving
   // it the max alignment of all the non-virtual data in the class.  The
   // resulting layout is essentially { vftbl, { nvdata } }.  This is completely
   // unnecessary, but we're not here to pass judgment.
-  updateAlignment(PointerAlignment);
-  if (Is64BitMode)
-    Size = Size.RoundUpToAlignment(PointerAlignment) + PointerSize;
-  else
-    Size = Size.RoundUpToAlignment(PointerAlignment) + Alignment;
+  if (!Is64BitMode && Alignment > PointerSize)
+    Size += Alignment - PointerSize;
 }
 
 void

Modified: cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp?rev=198059&r1=198058&r2=198059&view=diff
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp (original)
+++ cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp Thu Dec 26 16:09:12 2013
@@ -119,6 +119,7 @@ struct A1 { long long a; };
 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)
@@ -138,8 +139,41 @@ struct C1 : B1 {};
 // CHECK-X64:      | [sizeof=24, align=8
 // CHECK-X64:      |  nvsize=9, nvalign=1]
 
+struct CA0 {
+	CA0() {}
+};
+struct CA1 : virtual CA0 {
+	CA1() {}
+};
+#pragma pack(push, 1)
+struct CA2 : public CA1, public CA0 {
+	virtual void CA2Method() {}
+	CA2() {}
+};
+#pragma pack(pop)
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK:    0 | struct CA2
+// CHECK:    0 |   (CA2 vftable pointer)
+// CHECK:    4 |   struct CA1 (base)
+// CHECK:    4 |     (CA1 vbtable pointer)
+// CHECK:    9 |   struct CA0 (base) (empty)
+// CHECK:    9 |   struct CA0 (virtual base) (empty)
+// CHECK:      | [sizeof=9, align=1
+// CHECK:      |  nvsize=9, nvalign=1]
+// CHECK-C64: *** Dumping AST Record Layout
+// CHECK-C64:    0 | struct CA2
+// CHECK-C64:    0 |   (CA2 vftable pointer)
+// CHECK-C64:    8 |   struct CA1 (base)
+// CHECK-C64:    8 |     (CA1 vbtable pointer)
+// CHECK-C64:   17 |   struct CA0 (base) (empty)
+// CHECK-C64:   17 |   struct CA0 (virtual base) (empty)
+// CHECK-C64:      | [sizeof=17, align=1
+// CHECK-C64:      |  nvsize=17, nvalign=1]
+
 int a[
 sizeof(X)+
 sizeof(Y)+
 sizeof(Z)+
-sizeof(C1)];
+sizeof(C1)+
+sizeof(CA2)];





More information about the cfe-commits mailing list