From d23cab2962e24b2c7834da57006ae69e13832992 Mon Sep 17 00:00:00 2001 From: Timur Iskhodzhanov Date: Wed, 26 Mar 2014 08:12:53 +0000 Subject: [PATCH] Fix PR19066 - 0-sized vftable in the presence of virtual inheritance Reviewed at http://llvm-reviews.chandlerc.com/D3181 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204786 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/VTableBuilder.cpp | 11 ++++++++++- .../microsoft-abi-vtables-virtual-inheritance.cpp | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index eef91f7416..2d1e1a2408 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -2531,6 +2531,7 @@ private: BasesSetVectorTy VisitedBases; AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, 0, VisitedBases); + assert(Components.size() && "vftable can't be empty"); assert(MethodVFTableLocations.empty()); for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(), @@ -2793,6 +2794,14 @@ bool VFTableBuilder::NeedsReturnAdjustingThunk(const CXXMethodDecl *MD) { return false; } +static bool isDirectVBase(const CXXRecordDecl *Base, const CXXRecordDecl *RD) { + for (const auto &B : RD->bases()) { + if (B.isVirtual() && B.getType()->getAsCXXRecordDecl() == Base) + return true; + } + return false; +} + void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, const CXXRecordDecl *LastVBase, BasesSetVectorTy &VisitedBases) { @@ -2808,7 +2817,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, CharUnits NextBaseOffset; if (BaseDepth < WhichVFPtr.PathToBaseWithVPtr.size()) { NextBase = WhichVFPtr.PathToBaseWithVPtr[BaseDepth]; - if (Layout.getVBaseOffsetsMap().count(NextBase)) { + if (isDirectVBase(NextBase, RD)) { NextLastVBase = NextBase; NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(NextBase); } else { diff --git a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp index 634f583e73..1947b59715 100644 --- a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp +++ b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp @@ -660,6 +660,21 @@ C c; // MANGLING-DAG: @"\01??_7C@pr17748@@6BB@1@@" } +namespace pr19066 { +struct X : virtual B {}; + +struct Y : virtual X, B { + Y(); + // CHECK-LABEL: VFTable for 'B' in 'pr19066::X' in 'pr19066::Y' (1 entry). + // CHECK-NEXT: 0 | void B::g() + + // CHECK-LABEL: VFTable for 'B' in 'pr19066::Y' (1 entry). + // CHECK-NEXT: 0 | void B::g() +}; + +Y::Y() {} +} + namespace pr19240 { struct A { virtual void c(); -- 2.40.0