From 0378bf0840335c6d56b2f1b51079522054f7da4f Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 28 Feb 2010 18:08:38 +0000 Subject: [PATCH] When laying out vtables for virtual bases in construction vtables, we need to check if the vtable is a primary base in the layout class. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97402 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVtable.cpp | 19 ++++++++++++++++--- test/CodeGenCXX/vtable-layout.cpp | 21 ++++++++++++++------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 4f3cdde2d8..40a7b2f180 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -1799,9 +1799,22 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, // Check if this base has a primary base. if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) { - // Check if it's virtual - if (Layout.getPrimaryBaseWasVirtual()) - PrimaryVirtualBases.insert(PrimaryBase); + + // Check if it's virtual. + if (Layout.getPrimaryBaseWasVirtual()) { + bool IsPrimaryVirtualBase = true; + + if (isBuildingConstructorVtable()) { + // Check if the base is actually a primary base in the class we use for + // layout. + // FIXME: Is this check enough? + if (MostDerivedClassOffset != 0) + IsPrimaryVirtualBase = false; + } + + if (IsPrimaryVirtualBase) + PrimaryVirtualBases.insert(PrimaryBase); + } } // Traverse bases, looking for more primary virtual bases. diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index dce7461e04..615ab6f564 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -926,6 +926,13 @@ namespace Test24 { // Another construction vtable test. +struct A { + virtual void f(); +}; + +struct B : virtual A { }; +struct C : virtual A { }; + // CHECK: Vtable for 'Test24::D' (10 entries). // CHECK-NEXT: 0 | vbase_offset (0) // CHECK-NEXT: 1 | vcall_offset (0) @@ -952,13 +959,13 @@ namespace Test24 { // CHECK-NEXT: -- (Test24::B, 0) vtable address -- // CHECK-NEXT: 4 | void Test24::A::f() -struct A { - virtual void f(); -}; - -struct B : virtual A { }; -struct C : virtual A { }; - +// CHECK: Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries). +// CHECK-NEXT: 0 | vbase_offset (-8) +// CHECK-NEXT: 1 | vcall_offset (-8) +// CHECK-NEXT: 2 | offset_to_top (0) +// CHECK-NEXT: 3 | Test24::C RTTI +// CHECK-NEXT: -- (Test24::A, 8) vtable address -- +// CHECK-NEXT: -- (Test24::C, 8) vtable address -- struct D : B, C { virtual void f(); }; -- 2.40.0