From 0c12b36ebb1d8a1f4785dd321431f8b5da3ac8c7 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 18 Feb 2014 22:51:52 +0000 Subject: MS ABI: Remove nv adjustment from direct vdtor calls and prologues Summary: Generally the vector deleting dtor, which we model as a vtable thunk, takes care of non-virtual adjustment and delegates to the other destructor variants. The other non-complete destructor variants assume that 'this' on entry points to the virtual base subobject that first declared the virtual destructor. We need to change the adjustment in both the prologue and the vdtor call setup. Reviewers: timurrrr CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D2821 llvm-svn: 201612 --- clang/lib/CodeGen/MicrosoftCXXABI.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'clang/lib/CodeGen/MicrosoftCXXABI.cpp') diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index d8c7d6ee5ab..572bb098c93 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -601,6 +601,13 @@ llvm::Value *MicrosoftCXXABI::adjustThisArgumentForVirtualCall( unsigned AS = cast(This->getType())->getAddressSpace(); llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS); CharUnits StaticOffset = ML.VFPtrOffset; + + // Base destructors expect 'this' to point to the beginning of the base + // subobject, not the first vfptr that happens to contain the virtual dtor. + // However, we still need to apply the virtual base adjustment. + if (isa(MD) && GD.getDtorType() == Dtor_Base) + StaticOffset = CharUnits::Zero(); + if (ML.VBase) { bool AvoidVirtualOffset = false; if (isa(MD) && GD.getDtorType() == Dtor_Base) { @@ -729,6 +736,14 @@ llvm::Value *MicrosoftCXXABI::adjustThisParameterInVirtualFunctionPrologue( MicrosoftVTableContext::MethodVFTableLocation ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD); CharUnits Adjustment = ML.VFPtrOffset; + + // Normal virtual instance methods need to adjust from the vfptr that first + // defined the virtual method to the virtual base subobject, but destructors + // do not. The vector deleting destructor thunk applies this adjustment for + // us if necessary. + if (isa(MD)) + Adjustment = CharUnits::Zero(); + if (ML.VBase) { const ASTRecordLayout &DerivedLayout = CGF.getContext().getASTRecordLayout(MD->getParent()); -- cgit v1.2.3