From: Timur Iskhodzhanov Date: Tue, 29 Oct 2013 14:13:45 +0000 (+0000) Subject: Fix an assertion when handling a custom case of virtual inheritance; also reduce... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d647efb48af96dfc56d31736beb1052536ee81ff;p=clang Fix an assertion when handling a custom case of virtual inheritance; also reduce code duplication git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193610 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index a161802b29..3031955452 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -2730,28 +2730,6 @@ VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD, return Ret; } -static const CXXMethodDecl* -FindDirectlyOverriddenMethodInBases(const CXXMethodDecl *MD, - BasesSetVectorTy &Bases) { - // We can't just iterate over the overridden methods and return the first one - // which has its parent in Bases, e.g. this doesn't work when we have - // multiple subobjects of the same type that have its virtual function - // overridden. - for (int I = Bases.size(), E = 0; I != E; --I) { - const CXXRecordDecl *CurrentBase = Bases[I - 1]; - - for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), - E = MD->end_overridden_methods(); I != E; ++I) { - const CXXMethodDecl *OverriddenMD = *I; - - if (OverriddenMD->getParent() == CurrentBase) - return OverriddenMD; - } - } - - return 0; -} - static void GroupNewVirtualOverloads( const CXXRecordDecl *RD, SmallVector &VirtualMethods) { @@ -2843,7 +2821,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, // Check if this virtual member function overrides // a method in one of the visited bases. if (const CXXMethodDecl *OverriddenMD = - FindDirectlyOverriddenMethodInBases(MD, VisitedBases)) { + FindNearestOverriddenMethod(MD, VisitedBases)) { MethodInfoMapTy::iterator OverriddenMDIterator = MethodInfoMap.find(OverriddenMD); @@ -2887,7 +2865,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth, // FIXME: this is O(N^2), can be O(N). const CXXMethodDecl *SubOverride = OverriddenMD; while ((SubOverride = - FindDirectlyOverriddenMethodInBases(SubOverride, VisitedBases))) { + FindNearestOverriddenMethod(SubOverride, VisitedBases))) { MethodInfoMapTy::iterator SubOverrideIterator = MethodInfoMap.find(SubOverride); if (SubOverrideIterator == MethodInfoMap.end()) diff --git a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp index 7bdc97ca08..cfbdad941a 100644 --- a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp +++ b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp @@ -9,7 +9,8 @@ // RUN: FileCheck --check-prefix=TEST5 %s < %t // RUN: FileCheck --check-prefix=TEST6 %s < %t // RUN: FileCheck --check-prefix=TEST7 %s < %t -// RUN: FileCheck --check-prefix=TEST8 %s < %t +// RUN: FileCheck --check-prefix=TEST8-X %s < %t +// RUN: FileCheck --check-prefix=TEST8-Z %s < %t // RUN: FileCheck --check-prefix=TEST9-Y %s < %t // RUN: FileCheck --check-prefix=TEST9-Z %s < %t // RUN: FileCheck --check-prefix=TEST9-W %s < %t @@ -236,16 +237,16 @@ namespace Test8 { // This is a typical diamond inheritance with a shared 'A' vbase. struct X : D, C { - // TEST8: VFTable for 'D' in 'Test8::X' (1 entries). - // TEST8-NEXT: 0 | void D::h() + // TEST8-X: VFTable for 'D' in 'Test8::X' (1 entries). + // TEST8-X-NEXT: 0 | void D::h() - // TEST8: VFTable for 'A' in 'D' in 'Test8::X' (2 entries). - // TEST8-NEXT: 0 | void Test8::X::f() - // TEST8-NEXT: 1 | void A::z() + // TEST8-X: VFTable for 'A' in 'D' in 'Test8::X' (2 entries). + // TEST8-X-NEXT: 0 | void Test8::X::f() + // TEST8-X-NEXT: 1 | void A::z() - // TEST8: VFTable indices for 'Test8::X' (1 entries). - // TEST8-NEXT: via vbtable index 1, vfptr at offset 0 - // TEST8-NEXT: 0 | void Test8::X::f() + // TEST8-X: VFTable indices for 'Test8::X' (1 entries). + // TEST8-X-NEXT: via vbtable index 1, vfptr at offset 0 + // TEST8-X-NEXT: 0 | void Test8::X::f() // MANGLING-DAG: @"\01??_7X@Test8@@6BA@@@" // MANGLING-DAG: @"\01??_7X@Test8@@6BD@@@" @@ -254,6 +255,21 @@ struct X : D, C { }; X x; + +// Another diamond inheritance which led to AST crashes. +struct Y : virtual A {}; + +class Z : Y, C { + // TEST8-Z: VFTable for 'A' in 'Test8::Y' in 'Test8::Z' (2 entries). + // TEST8-Z-NEXT: 0 | void Test8::Z::f() + // TEST8-Z-NEXT: 1 | void A::z() + + // TEST8-Z: VFTable indices for 'Test8::Z' (1 entries). + // TEST8-Z-NEXT: via vbtable index 1, vfptr at offset 0 + // TEST8-Z-NEXT: 0 | void Test8::Z::f() + virtual void f(); +}; +Z z; } namespace Test9 {