[PATCH] Fix PR20479 -- missing vftable slots in case of virtual inheritance vs return adjusting thunks
Timur Iskhodzhanov
timurrrr at google.com
Fri Aug 8 04:36:52 PDT 2014
Hi rnk,
http://reviews.llvm.org/D4829
Files:
lib/AST/VTableBuilder.cpp
test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
Index: lib/AST/VTableBuilder.cpp
===================================================================
--- lib/AST/VTableBuilder.cpp
+++ lib/AST/VTableBuilder.cpp
@@ -3173,10 +3173,17 @@
if (ForVBTables ? Layout.hasOwnVBPtr() : Layout.hasOwnVFPtr())
Paths.push_back(new VPtrInfo(RD));
- // Recursive case: get all the vbtables from our bases and remove anything
- // that shares a virtual base.
+ // Recursive case: get all the vtables from our bases and remove anything
+ // that shares a virtual base. Look at non-virtual bases first so we get
+ // longer inheritance paths from the derived class to the virtual bases.
+ llvm::SmallVector<CXXBaseSpecifier, 10> Bases;
+ std::copy_if(RD->bases_begin(), RD->bases_end(), std::back_inserter(Bases),
+ [](CXXBaseSpecifier bs) { return !bs.isVirtual(); });
+ std::copy_if(RD->bases_begin(), RD->bases_end(), std::back_inserter(Bases),
+ [](CXXBaseSpecifier bs) { return bs.isVirtual(); });
+
llvm::SmallPtrSet<const CXXRecordDecl*, 4> VBasesSeen;
- for (const auto &B : RD->bases()) {
+ for (const auto &B : Bases) {
const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
if (B.isVirtual() && VBasesSeen.count(Base))
continue;
Index: test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
+++ test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
@@ -104,3 +104,27 @@
// GLOBALS-LABEL: @"\01??_7K at test2@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
}
+
+namespace pr20479 {
+struct A {
+ virtual A *f();
+};
+
+struct B : virtual A {
+ virtual B *f();
+};
+
+struct C : virtual A, B {
+// VFTABLES-LABEL: VFTable for 'pr20479::A' in 'pr20479::B' in 'pr20479::C' (2 entries).
+// VFTABLES-NEXT: 0 | pr20479::B *pr20479::B::f()
+// VFTABLES-NEXT: [return adjustment (to type 'struct pr20479::A *'): vbase #1, 0 non-virtual]
+// VFTABLES-NEXT: 1 | pr20479::B *pr20479::B::f()
+ C();
+};
+
+C::C() {}
+
+// GLOBALS-LABEL: @"\01??_7C at pr20479@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+// GLOBALS: @"\01?f at B@pr20479@@QAEPAUA at 2@XZ"
+// GLOBALS: @"\01?f at B@pr20479@@UAEPAU12 at XZ"
+}
Index: test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
+++ test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
@@ -573,17 +573,17 @@
// PR19172: Yet another diamond we miscompiled.
struct R : virtual Q, X {
+ // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::R' (2 entries).
+ // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+ // CHECK-NEXT: 1 | void vdtors::X::zzz()
+
// CHECK-LABEL: VFTable for 'vdtors::Q' in 'vdtors::R' (1 entry).
// CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
// CHECK-NEXT: [this adjustment: -8 non-virtual]
// CHECK-LABEL: Thunks for 'vdtors::R::~R()' (1 entry).
// CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
- // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::R' (2 entries).
- // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
- // CHECK-NEXT: 1 | void vdtors::X::zzz()
-
// CHECK-LABEL: VFTable indices for 'vdtors::R' (1 entry).
// CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
virtual ~R();
@@ -694,10 +694,10 @@
struct Y : virtual X, B {
Y();
- // CHECK-LABEL: VFTable for 'B' in 'pr19066::X' in 'pr19066::Y' (1 entry).
+ // CHECK-LABEL: VFTable for 'B' in 'pr19066::Y' (1 entry).
// CHECK-NEXT: 0 | void B::g()
- // CHECK-LABEL: VFTable for 'B' in 'pr19066::Y' (1 entry).
+ // CHECK-LABEL: VFTable for 'B' in 'pr19066::X' in 'pr19066::Y' (1 entry).
// CHECK-NEXT: 0 | void B::g()
};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4829.12304.patch
Type: text/x-patch
Size: 3828 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140808/0398be5d/attachment.bin>
More information about the cfe-commits
mailing list