diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
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<llvm::PointerType>(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<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) + StaticOffset = CharUnits::Zero(); + if (ML.VBase) { bool AvoidVirtualOffset = false; if (isa<CXXDestructorDecl>(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<CXXDestructorDecl>(MD)) + Adjustment = CharUnits::Zero(); + if (ML.VBase) { const ASTRecordLayout &DerivedLayout = CGF.getContext().getASTRecordLayout(MD->getParent()); |