From fbf05613db16a521ce124391388891c488c47a0c Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 17 Apr 2010 17:24:33 +0000 Subject: [PATCH] Fix a bug where we would sometimes incorrectly mark an vtable function as unused. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101643 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVTables.cpp | 9 +++---- test/CodeGenCXX/vtable-layout.cpp | 39 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index 462384f82f..28530ecbb4 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -1608,15 +1608,12 @@ VTableBuilder::AddMethod(const CXXMethodDecl *MD, static bool OverridesIndirectMethodInBases(const CXXMethodDecl *MD, VTableBuilder::PrimaryBasesSetVectorTy &Bases) { + if (Bases.count(MD->getParent())) + return true; + for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(), E = MD->end_overridden_methods(); I != E; ++I) { const CXXMethodDecl *OverriddenMD = *I; - const CXXRecordDecl *OverriddenRD = OverriddenMD->getParent(); - assert(OverriddenMD->isCanonicalDecl() && - "Should have the canonical decl of the overridden RD!"); - - if (Bases.count(OverriddenRD)) - return true; // Check "indirect overriders". if (OverridesIndirectMethodInBases(OverriddenMD, Bases)) diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index 692e8deef3..f2f5179d4a 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -1598,3 +1598,42 @@ struct H : F, G { void H::h() { } } + +namespace Test36 { + +// Test that we don't mark B::f as unused in the vtable for D. + +struct A { + virtual void f(); +}; + +struct B : virtual A { }; + +struct C : virtual A { + virtual void f(); +}; + +// CHECK: Vtable for 'Test36::D' (12 entries). +// CHECK-NEXT: 0 | vbase_offset (8) +// CHECK-NEXT: 1 | vbase_offset (8) +// CHECK-NEXT: 2 | vcall_offset (0) +// CHECK-NEXT: 3 | offset_to_top (0) +// CHECK-NEXT: 4 | Test36::D RTTI +// CHECK-NEXT: -- (Test36::C, 0) vtable address -- +// CHECK-NEXT: -- (Test36::D, 0) vtable address -- +// CHECK-NEXT: 5 | void Test36::C::f() +// CHECK-NEXT: 6 | void Test36::D::g() +// CHECK-NEXT: 7 | vbase_offset (0) +// CHECK-NEXT: 8 | vcall_offset (-8) +// CHECK-NEXT: 9 | offset_to_top (-8) +// CHECK-NEXT: 10 | Test36::D RTTI +// CHECK-NEXT: -- (Test36::A, 8) vtable address -- +// CHECK-NEXT: -- (Test36::B, 8) vtable address -- +// CHECK-NEXT: 11 | void Test36::C::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +struct D : virtual B, C { + virtual void g(); +}; +void D::g() { } + +}