summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWarren Hunt <whunt@google.com>2013-12-26 22:09:12 +0000
committerWarren Hunt <whunt@google.com>2013-12-26 22:09:12 +0000
commit50de3522e699b23dee10bb8d1ef962c27b56f026 (patch)
tree5e159c6d00c409b30c82ad097c53d45b2bfe1b7d
parentf4355eef5e415b84f6456d86c608146560773962 (diff)
downloadbcm5719-llvm-50de3522e699b23dee10bb8d1ef962c27b56f026.tar.gz
bcm5719-llvm-50de3522e699b23dee10bb8d1ef962c27b56f026.zip
[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. llvm-svn: 198059
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp9
-rw-r--r--clang/test/Layout/ms-x86-pack-and-align.cpp36
2 files changed, 39 insertions, 6 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 74010ce7aa0..832bfef90c9 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2316,15 +2316,14 @@ void MicrosoftRecordLayoutBuilder::layoutVFPtr(const CXXRecordDecl *RD) {
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
diff --git a/clang/test/Layout/ms-x86-pack-and-align.cpp b/clang/test/Layout/ms-x86-pack-and-align.cpp
index c7bf4d31579..d9bca99b1c1 100644
--- a/clang/test/Layout/ms-x86-pack-and-align.cpp
+++ b/clang/test/Layout/ms-x86-pack-and-align.cpp
@@ -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)];
OpenPOWER on IntegriCloud