summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorTimur Iskhodzhanov <timurrrr@google.com>2014-08-09 17:08:06 +0000
committerTimur Iskhodzhanov <timurrrr@google.com>2014-08-09 17:08:06 +0000
commitf97c973c2e40400531663a2020e6c3514baaf7b2 (patch)
tree2c02e2f0df40e390f5d9188ff28b75488c5ae0be /clang/lib
parent9cf3625742dd8c1ed38e74ca01101dbaaac4e7cf (diff)
downloadbcm5719-llvm-f97c973c2e40400531663a2020e6c3514baaf7b2.tar.gz
bcm5719-llvm-f97c973c2e40400531663a2020e6c3514baaf7b2.zip
Fix PR20479 -- missing vftable slots in case of virtual inheritance vs return adjusting thunks
Reviewed at http://reviews.llvm.org/D4829 llvm-svn: 215285
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/VTableBuilder.cpp11
1 files changed, 9 insertions, 2 deletions
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index fa1127f58f9..42fafde4a5d 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -3174,9 +3174,16 @@ void MicrosoftVTableContext::computeVTablePaths(bool ForVBTables,
Paths.push_back(new VPtrInfo(RD));
// Recursive case: get all the vbtables from our bases and remove anything
- // that shares a virtual base.
+ // 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;
OpenPOWER on IntegriCloud