r192822 - [-cxx-abi microsoft] Fix this argument/parameter offsets for virtual destructors in the presence of virtual bases
Reid Kleckner
rnk at google.com
Wed Oct 16 16:35:09 PDT 2013
On Wed, Oct 16, 2013 at 11:24 AM, Timur Iskhodzhanov <timurrrr at google.com>wrote:
> Author: timurrrr
> Date: Wed Oct 16 13:24:06 2013
> New Revision: 192822
>
> URL: http://llvm.org/viewvc/llvm-project?rev=192822&view=rev
> Log:
> [-cxx-abi microsoft] Fix this argument/parameter offsets for virtual
> destructors in the presence of virtual bases
>
> Reviewed at http://llvm-reviews.chandlerc.com/D1939
>
> Modified:
> cfe/trunk/lib/AST/VTableBuilder.cpp
> cfe/trunk/lib/CodeGen/CGClass.cpp
> cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
>
> cfe/trunk/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
> cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
>
> cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp
> cfe/trunk/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
>
> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=192822&r1=192821&r2=192822&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Oct 16 13:24:06 2013
> @@ -563,21 +563,65 @@ llvm::Value *MicrosoftCXXABI::adjustThis
> CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) {
> GD = GD.getCanonicalDecl();
> const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
> - if (isa<CXXDestructorDecl>(MD))
> - return This;
> + // FIXME: consider splitting the vdtor vs regular method code into two
> + // functions.
>
> + GlobalDecl LookupGD = GD;
> + if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
> + // Complete dtors take a pointer to the complete object,
> + // thus don't need adjustment.
> + if (GD.getDtorType() == Dtor_Complete)
> + return This;
> +
> + // There's only Dtor_Deleting in vftable but it shares the this
> adjustment
> + // with the base one, so look up the deleting one instead.
> + LookupGD = GlobalDecl(DD, Dtor_Deleting);
> + }
> MicrosoftVFTableContext::MethodVFTableLocation ML =
> - CGM.getVFTableContext().getMethodVFTableLocation(GD);
> + CGM.getVFTableContext().getMethodVFTableLocation(LookupGD);
>
> unsigned AS =
> cast<llvm::PointerType>(This->getType())->getAddressSpace();
> llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS);
> + CharUnits StaticOffset = ML.VFTableOffset;
> if (ML.VBase) {
> - This = CGF.Builder.CreateBitCast(This, charPtrTy);
> - llvm::Value *VBaseOffset = CGM.getCXXABI()
> - .GetVirtualBaseClassOffset(CGF, This, MD->getParent(), ML.VBase);
> - This = CGF.Builder.CreateInBoundsGEP(This, VBaseOffset);
> + bool AvoidVirtualOffset = false;
> + if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) {
> + // A base destructor can only be called from a complete destructor
> of the
> + // same record type or another destructor of a more derived type.
> + const CXXRecordDecl *CurRD =
> + cast<CXXDestructorDecl>(CGF.CurGD.getDecl())->getParent();
>
This cast is failing. I'm trying to reduce it. I believe there are ways
to call the base dtor for something other than the complete dtor. The hack
I added that makes us call the base dtor instead of complete dtor, for
example.
> +
> + if (MD->getParent() == CurRD) {
> + assert(CGF.CurGD.getDtorType() == Dtor_Complete);
> + // We're calling the main base dtor from a complete dtor, so we
> know the
> + // "this" offset statically.
> + AvoidVirtualOffset = true;
> + } else {
> + // Let's see if we try to call a destructor of a non-virtual base.
> + for (CXXRecordDecl::base_class_const_iterator I =
> CurRD->bases_begin(),
> + E = CurRD->bases_end(); I != E; ++I) {
> + if (I->getType()->getAsCXXRecordDecl() != MD->getParent())
> + continue;
> + // If we call a base destructor for a non-virtual base, we
> statically
> + // know where it expects the vfptr and "this" to be.
> + AvoidVirtualOffset = true;
> + break;
> + }
> + }
> + }
> +
> + if (AvoidVirtualOffset) {
> + const ASTRecordLayout &Layout =
> + CGF.getContext().getASTRecordLayout(MD->getParent());
> + // This reflects the logic from VFTableBuilder::ComputeThisOffset().
> + StaticOffset += Layout.getVBaseClassOffset(ML.VBase);
> + } else {
> + This = CGF.Builder.CreateBitCast(This, charPtrTy);
> + llvm::Value *VBaseOffset = CGM.getCXXABI()
> + .GetVirtualBaseClassOffset(CGF, This, MD->getParent(),
> ML.VBase);
> + This = CGF.Builder.CreateInBoundsGEP(This, VBaseOffset);
> + }
> }
> - CharUnits StaticOffset = ML.VFTableOffset;
> if (!StaticOffset.isZero()) {
> assert(StaticOffset.isPositive());
> This = CGF.Builder.CreateBitCast(This, charPtrTy);
> @@ -625,8 +669,18 @@ llvm::Value *MicrosoftCXXABI::adjustThis
> CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) {
> GD = GD.getCanonicalDecl();
> const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
> - if (isa<CXXDestructorDecl>(MD))
> - return This;
> +
> + GlobalDecl LookupGD = GD;
> + if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
> + // Complete destructors take a pointer to the complete object as a
> + // parameter, thus don't need this adjustment.
> + if (GD.getDtorType() == Dtor_Complete)
> + return This;
> +
> + // There's no Dtor_Base in vftable but it shares the this adjustment
> with
> + // the deleting one, so look it up instead.
> + LookupGD = GlobalDecl(DD, Dtor_Deleting);
> + }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131016/25a25d3b/attachment.html>
More information about the cfe-commits
mailing list