From bf554f63bffa7db32b5f343f6fd075501b97d401 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Thu, 25 Feb 2010 22:18:35 +0000 Subject: [PATCH] Fux a bug where we were trying to add overriders for non-virtual bases of virtual bases more than once. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97173 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVtable.cpp | 6 +++--- test/CodeGenCXX/vtable-layout.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 5ebe816068..a6b8eb6d3d 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -261,10 +261,10 @@ static BaseOffset ComputeBaseOffset(ASTContext &Context, // Check the base class offset. const ASTRecordLayout &Layout = Context.getASTRecordLayout(Element.Class); - + const RecordType *BaseType = Element.Base->getType()->getAs(); const CXXRecordDecl *Base = cast(BaseType->getDecl()); - + NonVirtualOffset += Layout.getBaseClassOffset(Base); } @@ -512,7 +512,7 @@ void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base, if (!BaseDecl->isPolymorphic()) continue; - bool IsVisitedVirtualBase = false; + bool IsVisitedVirtualBase = BaseSubobjectIsVisitedVBase; uint64_t BaseOffset; if (I->isVirtual()) { if (!VisitedVirtualBases.insert(BaseDecl)) diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index efd0d2f7bc..c22222f9ce 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -510,3 +510,32 @@ void C::f() { } } +namespace Test14 { + +// Verify that we handle A being a non-virtual base of B, which is a virtual base. + +struct A { + virtual void f(); +}; + +struct B : A { }; + +struct C : virtual B { }; + +// CHECK: Vtable for 'Test14::D' (5 entries). +// CHECK-NEXT: 0 | vbase_offset (0) +// CHECK-NEXT: 1 | vcall_offset (0) +// CHECK-NEXT: 2 | offset_to_top (0) +// CHECK-NEXT: 3 | Test14::D RTTI +// CHECK-NEXT: -- (Test14::A, 0) vtable address -- +// CHECK-NEXT: -- (Test14::B, 0) vtable address -- +// CHECK-NEXT: -- (Test14::C, 0) vtable address -- +// CHECK-NEXT: -- (Test14::D, 0) vtable address -- +// CHECK-NEXT: 4 | void Test14::D::f() +struct D : C, virtual B { + virtual void f(); +}; +void D::f() { } + +} + -- 2.40.0