From d7fdae5ea0158f91f0683044bb3a7dee0426bfe0 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Wed, 10 Mar 2010 03:02:01 +0000 Subject: [PATCH] When building construction vtables, we need to check if a primary virtual base is actually a primary virtual base in the layout class. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98131 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVtable.cpp | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index fbd0ed8fbe..8b239f2614 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -1238,6 +1238,7 @@ private: /// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this /// class hierarchy. void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, + uint64_t OffsetInLayoutClass, VisitedVirtualBasesSetTy &VBases); /// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the @@ -1699,7 +1700,8 @@ void VtableBuilder::LayoutVtable() { VisitedVirtualBasesSetTy VBases; // Determine the primary virtual bases. - DeterminePrimaryVirtualBases(MostDerivedClass, VBases); + DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset, + VBases); VBases.clear(); LayoutVtablesForVirtualBases(MostDerivedClass, VBases); @@ -1808,7 +1810,8 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base, } void -VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, +VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, + uint64_t OffsetInLayoutClass, VisitedVirtualBasesSetTy &VBases) { const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); @@ -1822,8 +1825,15 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, 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) + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); + + uint64_t PrimaryBaseOffsetInLayoutClass = + LayoutClassLayout.getVBaseClassOffset(PrimaryBase); + + // We know that the base is not a primary base in the layout class if + // the base offsets are different. + if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass) IsPrimaryVirtualBase = false; } @@ -1838,10 +1848,22 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl = cast(I->getType()->getAs()->getDecl()); - if (I->isVirtual() && !VBases.insert(BaseDecl)) - continue; + uint64_t BaseOffsetInLayoutClass; + + if (I->isVirtual()) { + if (!VBases.insert(BaseDecl)) + continue; + + const ASTRecordLayout &LayoutClassLayout = + Context.getASTRecordLayout(LayoutClass); - DeterminePrimaryVirtualBases(BaseDecl, VBases); + BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl); + } else { + BaseOffsetInLayoutClass = + OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl); + } + + DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases); } }