]> granicus.if.org Git - clang/commitdiff
PR17576: Fix assertion on polymorphic classes with small alignment
authorReid Kleckner <reid@kleckner.net>
Mon, 14 Oct 2013 21:14:05 +0000 (21:14 +0000)
committerReid Kleckner <reid@kleckner.net>
Mon, 14 Oct 2013 21:14:05 +0000 (21:14 +0000)
We have to reserve at least the width of a pointer for the vfptr.  For
classes with small alignment, we weren't reserving enough space, and
were overlapping the first field with the vfptr.

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

lib/AST/RecordLayoutBuilder.cpp
test/Layout/ms-x86-size-alignment-fail.cpp

index 05eeae154d0645e5cfe4b56116b3da396d564120..b0230ac6ef6657f7ec54a4266497589336505f46 100644 (file)
@@ -2660,8 +2660,8 @@ void MicrosoftRecordLayoutBuilder::layoutVFPtr(const CXXRecordDecl *RD) {
   // 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.
-  Size += Alignment;
   updateAlignment(PointerAlignment);
+  Size += Alignment;
 }
 
 void
index c15d3825c2db10d5b27c9bb4b3870056c86eadc7..6ce8a4b7203aeebce0085df8e776d3622ecf72ff 100644 (file)
@@ -58,10 +58,20 @@ struct E : virtual B0, virtual B1 {};
 // CHECK:    5 |   struct B1 (virtual base) (empty)
 // CHECK:      | [sizeof=8, align=4
 // CHECK:      |  nvsize=4, nvalign=4]
-       
+
+struct F { char a; virtual ~F(); };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK:    0 | struct F
+// CHECK:    0 |   (F vftable pointer)
+// CHECK:    4 |   char a
+// CHECK:      | [sizeof=8, align=4
+// CHECK:      |  nvsize=8, nvalign=4]
+
 int a[
 sizeof(A)+
 sizeof(B)+
 sizeof(C)+
 sizeof(D)+
-sizeof(E)];
+sizeof(E)+
+sizeof(F)];