diff options
author | Anders Carlsson <andersca@mac.com> | 2009-12-13 18:48:07 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-12-13 18:48:07 +0000 |
commit | 6153710ee3e7dc3014d5fb992bfb77d4af56ccac (patch) | |
tree | 819d6df3cef115840c572ac1e8b0b30de75a5aff /lib/CodeGen/CGExprCXX.cpp | |
parent | 5d0d815586860156ec3f49470f972f38b19ad7e2 (diff) |
If the usual array deallocation function of a class takes two arguments, we need to pass the number of bytes allocated to the deallocation function, just not the number of bytes in a single element.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91246 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 73 |
1 files changed, 46 insertions, 27 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index ad8734d8da..9d1ad431be 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -250,10 +250,31 @@ void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD, DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy)); if (DeleteFTy->getNumArgs() == 2) { + uint64_t DeleteTypeSize = getContext().getTypeSize(DeleteTy) / 8; QualType SizeTy = DeleteFTy->getArgType(1); - uint64_t SizeVal = getContext().getTypeSize(DeleteTy) / 8; - llvm::Constant *Size = llvm::ConstantInt::get(ConvertType(SizeTy), - SizeVal); + llvm::Value *Size = + llvm::ConstantInt::get(ConvertType(SizeTy), DeleteTypeSize); + + if (DeleteFD->getOverloadedOperator() == OO_Array_Delete) { + // We need to get the number of elements in the array from the cookie. + uint64_t DeleteTypeAlign = getContext().getTypeAlign(DeleteTy); + unsigned CookiePadding = std::max(getContext().getTypeSize(SizeTy), + DeleteTypeAlign) / 8; + assert(CookiePadding && "CookiePadding should not be 0."); + + uint64_t CookieOffset = + CookiePadding - getContext().getTypeSize(SizeTy) / 8; + llvm::Value *NumElementsPtr = + Builder.CreateConstInBoundsGEP1_64(Ptr, CookieOffset); + NumElementsPtr = + Builder.CreateBitCast(NumElementsPtr, + ConvertType(SizeTy)->getPointerTo()); + llvm::Value *NumElements = Builder.CreateLoad(NumElementsPtr); + + // Multiply the size with the number of elements. + Size = Builder.CreateMul(NumElements, Size); + } + DeleteArgs.push_back(std::make_pair(RValue::get(Size), SizeTy)); } @@ -303,31 +324,29 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { QualType SizeTy = getContext().getSizeType(); uint64_t CookiePadding = std::max(getContext().getTypeSize(SizeTy), static_cast<uint64_t>(getContext().getTypeAlign(DeleteTy))) / 8; - if (CookiePadding) { - llvm::Type *Ptr8Ty = - llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); - uint64_t CookieOffset = - CookiePadding - getContext().getTypeSize(SizeTy) / 8; - llvm::Value *AllocatedObjectPtr = - Builder.CreateConstInBoundsGEP1_64( - Builder.CreateBitCast(Ptr, Ptr8Ty), -CookiePadding); - llvm::Value *NumElementsPtr = - Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr, - CookieOffset); - NumElementsPtr = Builder.CreateBitCast(NumElementsPtr, - ConvertType(SizeTy)->getPointerTo()); + assert(CookiePadding && "CookiePadding should not be 0."); + + const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); + uint64_t CookieOffset = + CookiePadding - getContext().getTypeSize(SizeTy) / 8; + llvm::Value *AllocatedObjectPtr = + Builder.CreateConstInBoundsGEP1_64( + Builder.CreateBitCast(Ptr, Int8PtrTy), + -CookiePadding); + llvm::Value *NumElementsPtr = + Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr, + CookieOffset); + NumElementsPtr = Builder.CreateBitCast(NumElementsPtr, + ConvertType(SizeTy)->getPointerTo()); - llvm::Value *NumElements = - Builder.CreateLoad(NumElementsPtr); - NumElements = - Builder.CreateIntCast(NumElements, - llvm::Type::getInt64Ty(VMContext), false, - "count.tmp"); - EmitCXXAggrDestructorCall(Dtor, NumElements, Ptr); - Ptr = AllocatedObjectPtr; - } - } - else if (Dtor->isVirtual()) { + llvm::Value *NumElements = Builder.CreateLoad(NumElementsPtr); + NumElements = + Builder.CreateIntCast(NumElements, + llvm::Type::getInt64Ty(VMContext), false, + "count.tmp"); + EmitCXXAggrDestructorCall(Dtor, NumElements, Ptr); + Ptr = AllocatedObjectPtr; + } else if (Dtor->isVirtual()) { const llvm::Type *Ty = CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor), /*isVariadic=*/false); |