aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-10-14 21:14:05 +0000
committerReid Kleckner <reid@kleckner.net>2013-10-14 21:14:05 +0000
commitbd5bd4b36a207a98c8433462701e48a4aa5a05a4 (patch)
treeb7ab3cf574be6d0dffeb70aa4269515509d32fbf
parente896819033434f0da3cd4831f2c14cdae1ce8719 (diff)
downloadllvm-bd5bd4b36a207a98c8433462701e48a4aa5a05a4.zip
llvm-bd5bd4b36a207a98c8433462701e48a4aa5a05a4.tar.gz
llvm-bd5bd4b36a207a98c8433462701e48a4aa5a05a4.tar.bz2
PR17576: Fix assertion on polymorphic classes with small alignment
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. llvm-svn: 192626
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp2
-rw-r--r--clang/test/Layout/ms-x86-size-alignment-fail.cpp14
2 files changed, 13 insertions, 3 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 05eeae1..b0230ac 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -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
diff --git a/clang/test/Layout/ms-x86-size-alignment-fail.cpp b/clang/test/Layout/ms-x86-size-alignment-fail.cpp
index c15d3825..6ce8a4b 100644
--- a/clang/test/Layout/ms-x86-size-alignment-fail.cpp
+++ b/clang/test/Layout/ms-x86-size-alignment-fail.cpp
@@ -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)];