From: Anders Carlsson Date: Fri, 4 Dec 2009 19:33:17 +0000 (+0000) Subject: When generating a virtual destructor, don't try to make a virtual call to the base... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fd12649cd54074ca9efa0774a7812e330619d198;p=clang When generating a virtual destructor, don't try to make a virtual call to the base class destructor because then we'll just re-enter the same destructor! This was done to fix PR5619, so I went ahead and passed a dummy VTT pointer for now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90578 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 636cc57b2a..6d96124a38 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -691,21 +691,29 @@ CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, EmitCXXMemberCall(D, Callee, This, ArgBeg, ArgEnd); } -void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, +void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, llvm::Value *This) { - if (D->isVirtual()) { - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(D), - /*isVariadic=*/false); + llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type); + + CallArgList Args; + + // Push the this ptr. + Args.push_back(std::make_pair(RValue::get(This), + DD->getThisType(getContext()))); + + // Add a VTT parameter if necessary. + // FIXME: This should not be a dummy null parameter! + if (Type == Dtor_Base && DD->getParent()->getNumVBases() != 0) { + QualType T = getContext().getPointerType(getContext().VoidPtrTy); - llvm::Value *Callee = BuildVirtualCall(D, Dtor_Deleting, This, Ty); - EmitCXXMemberCall(D, Callee, This, 0, 0); - return; + Args.push_back(std::make_pair(RValue::get(CGM.EmitNullConstant(T)), T)); } - llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type); - EmitCXXMemberCall(D, Callee, This, 0, 0); + // FIXME: We should try to share this code with EmitCXXMemberCall. + + QualType ResultType = DD->getType()->getAs()->getResultType(); + EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), Callee, Args, DD); } void diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp new file mode 100644 index 0000000000..976f56278e --- /dev/null +++ b/test/CodeGenCXX/virtual-destructor-calls.cpp @@ -0,0 +1,24 @@ +// RUN: clang-cc -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s + +struct A { + virtual ~A(); +}; + +struct B : A { + virtual ~B(); +}; + +// Deleting dtor. +// CHECK: define void @_ZN1BD0Ev +// CHECK: call void @_ZN1AD2Ev +// check: call void @_ZdlPv + +// Complete dtor. +// CHECK: define void @_ZN1BD1Ev +// CHECK: call void @_ZN1AD2Ev + +// Base dtor. +// CHECK: define void @_ZN1BD2Ev +// CHECK: call void @_ZN1AD2Ev + +B::~B() { }