diff options
author | John McCall <rjmccall@apple.com> | 2011-01-27 09:37:56 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-01-27 09:37:56 +0000 |
commit | 6ec278d1a354517e20f13a877481453ee7940c78 (patch) | |
tree | fad4d032592f9dbebc24c2fb8de1aed6149b950e /lib/CodeGen/ItaniumCXXABI.cpp | |
parent | d0370f59e79702ac908c81bf556519f91e9ca297 (diff) |
Do a proper recursive lookup when deciding whether a class's usual
deallocation function has a two-argument form. Store the result of this
check in new[] and delete[] nodes.
Fixes rdar://problem/8913519
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124373 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/ItaniumCXXABI.cpp')
-rw-r--r-- | lib/CodeGen/ItaniumCXXABI.cpp | 101 |
1 files changed, 46 insertions, 55 deletions
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index edc03b1bd1..ef5455c286 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -47,7 +47,9 @@ protected: return PtrDiffTy; } - bool NeedsArrayCookie(QualType ElementType); + bool NeedsArrayCookie(const CXXNewExpr *expr); + bool NeedsArrayCookie(const CXXDeleteExpr *expr, + QualType elementType); public: ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) : @@ -105,12 +107,14 @@ public: void EmitInstanceFunctionProlog(CodeGenFunction &CGF); - CharUnits GetArrayCookieSize(QualType ElementType); + CharUnits GetArrayCookieSize(const CXXNewExpr *expr); llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF, llvm::Value *NewPtr, llvm::Value *NumElements, + const CXXNewExpr *expr, QualType ElementType); void ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr, + const CXXDeleteExpr *expr, QualType ElementType, llvm::Value *&NumElements, llvm::Value *&AllocPtr, CharUnits &CookieSize); @@ -140,12 +144,14 @@ public: void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy); - CharUnits GetArrayCookieSize(QualType ElementType); + CharUnits GetArrayCookieSize(const CXXNewExpr *expr); llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF, llvm::Value *NewPtr, llvm::Value *NumElements, + const CXXNewExpr *expr, QualType ElementType); void ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr, + const CXXDeleteExpr *expr, QualType ElementType, llvm::Value *&NumElements, llvm::Value *&AllocPtr, CharUnits &CookieSize); @@ -794,67 +800,49 @@ void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF, /************************** Array allocation cookies **************************/ -bool ItaniumCXXABI::NeedsArrayCookie(QualType ElementType) { - ElementType = getContext().getBaseElementType(ElementType); - const RecordType *RT = ElementType->getAs<RecordType>(); - if (!RT) return false; - - const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - - // If the class has a non-trivial destructor, it always needs a cookie. - if (!RD->hasTrivialDestructor()) return true; +bool ItaniumCXXABI::NeedsArrayCookie(const CXXNewExpr *expr) { + // If the class's usual deallocation function takes two arguments, + // it needs a cookie. + if (expr->doesUsualArrayDeleteWantSize()) + return true; + + // Otherwise, if the class has a non-trivial destructor, it always + // needs a cookie. + const CXXRecordDecl *record = + expr->getAllocatedType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl(); + return (record && !record->hasTrivialDestructor()); +} +bool ItaniumCXXABI::NeedsArrayCookie(const CXXDeleteExpr *expr, + QualType elementType) { // If the class's usual deallocation function takes two arguments, - // it needs a cookie. Otherwise we don't need a cookie. - const CXXMethodDecl *UsualDeallocationFunction = 0; - - // Usual deallocation functions of this form are always found on the - // class. - // - // FIXME: what exactly is this code supposed to do if there's an - // ambiguity? That's possible with using declarations. - DeclarationName OpName = - getContext().DeclarationNames.getCXXOperatorName(OO_Array_Delete); - DeclContext::lookup_const_iterator Op, OpEnd; - for (llvm::tie(Op, OpEnd) = RD->lookup(OpName); Op != OpEnd; ++Op) { - const CXXMethodDecl *Delete = - cast<CXXMethodDecl>((*Op)->getUnderlyingDecl()); - - if (Delete->isUsualDeallocationFunction()) { - UsualDeallocationFunction = Delete; - break; - } - } - - // No usual deallocation function, we don't need a cookie. - if (!UsualDeallocationFunction) - return false; - - // The usual deallocation function doesn't take a size_t argument, - // so we don't need a cookie. - if (UsualDeallocationFunction->getNumParams() == 1) - return false; - - assert(UsualDeallocationFunction->getNumParams() == 2 && - "Unexpected deallocation function type!"); - return true; + // it needs a cookie. + if (expr->doesUsualArrayDeleteWantSize()) + return true; + + // Otherwise, if the class has a non-trivial destructor, it always + // needs a cookie. + const CXXRecordDecl *record = + elementType->getBaseElementTypeUnsafe()->getAsCXXRecordDecl(); + return (record && !record->hasTrivialDestructor()); } -CharUnits ItaniumCXXABI::GetArrayCookieSize(QualType ElementType) { - if (!NeedsArrayCookie(ElementType)) +CharUnits ItaniumCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) { + if (!NeedsArrayCookie(expr)) return CharUnits::Zero(); - // Padding is the maximum of sizeof(size_t) and alignof(ElementType) + // Padding is the maximum of sizeof(size_t) and alignof(elementType) ASTContext &Ctx = getContext(); return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()), - Ctx.getTypeAlignInChars(ElementType)); + Ctx.getTypeAlignInChars(expr->getAllocatedType())); } llvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, llvm::Value *NewPtr, llvm::Value *NumElements, + const CXXNewExpr *expr, QualType ElementType) { - assert(NeedsArrayCookie(ElementType)); + assert(NeedsArrayCookie(expr)); unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace(); @@ -887,6 +875,7 @@ llvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, void ItaniumCXXABI::ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr, + const CXXDeleteExpr *expr, QualType ElementType, llvm::Value *&NumElements, llvm::Value *&AllocPtr, @@ -896,7 +885,7 @@ void ItaniumCXXABI::ReadArrayCookie(CodeGenFunction &CGF, const llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS); // If we don't need an array cookie, bail out early. - if (!NeedsArrayCookie(ElementType)) { + if (!NeedsArrayCookie(expr, ElementType)) { AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy); NumElements = 0; CookieSize = CharUnits::Zero(); @@ -927,8 +916,8 @@ void ItaniumCXXABI::ReadArrayCookie(CodeGenFunction &CGF, NumElements = CGF.Builder.CreateLoad(NumElementsPtr); } -CharUnits ARMCXXABI::GetArrayCookieSize(QualType ElementType) { - if (!NeedsArrayCookie(ElementType)) +CharUnits ARMCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) { + if (!NeedsArrayCookie(expr)) return CharUnits::Zero(); // On ARM, the cookie is always: @@ -944,8 +933,9 @@ CharUnits ARMCXXABI::GetArrayCookieSize(QualType ElementType) { llvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, llvm::Value *NewPtr, llvm::Value *NumElements, + const CXXNewExpr *expr, QualType ElementType) { - assert(NeedsArrayCookie(ElementType)); + assert(NeedsArrayCookie(expr)); // NewPtr is a char*. @@ -978,6 +968,7 @@ llvm::Value *ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF, void ARMCXXABI::ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr, + const CXXDeleteExpr *expr, QualType ElementType, llvm::Value *&NumElements, llvm::Value *&AllocPtr, @@ -987,7 +978,7 @@ void ARMCXXABI::ReadArrayCookie(CodeGenFunction &CGF, const llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS); // If we don't need an array cookie, bail out early. - if (!NeedsArrayCookie(ElementType)) { + if (!NeedsArrayCookie(expr, ElementType)) { AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy); NumElements = 0; CookieSize = CharUnits::Zero(); |