diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2019-01-30 23:17:38 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2019-01-30 23:17:38 +0000 |
commit | 1f7eda5aac1dd9abd754044ba9883d4e81cc08c0 (patch) | |
tree | 37768be81e35c7beb77ee208167d63785b6c15e3 /clang/lib/CodeGen/CGObjC.cpp | |
parent | 547a83b4ebd1cbbe90b092634bf1d909ded48555 (diff) | |
download | bcm5719-llvm-1f7eda5aac1dd9abd754044ba9883d4e81cc08c0.tar.gz bcm5719-llvm-1f7eda5aac1dd9abd754044ba9883d4e81cc08c0.zip |
[CodeGenObjC] Handle exceptions when calling objc_alloc or objc_allocWithZone
objc_alloc and objc_allocWithZone may throw exceptions if the
underlying method does. If we're in a @try block, then make sure we
emit an invoke instead of a call.
rdar://47610407
Differential revision: https://reviews.llvm.org/D57476
llvm-svn: 352687
Diffstat (limited to 'clang/lib/CodeGen/CGObjC.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 3e64080e7b4..9a212969f4a 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -2022,7 +2022,8 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF, llvm::Value *value, llvm::Type *returnType, llvm::Constant *&fn, - StringRef fnName) { + StringRef fnName, + bool MayThrow) { if (isa<llvm::ConstantPointerNull>(value)) return value; @@ -2042,10 +2043,14 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF, value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy); // Call the function. - llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value); + llvm::CallBase *Inst = nullptr; + if (MayThrow) + Inst = CGF.EmitCallOrInvoke(fn, value); + else + Inst = CGF.EmitNounwindRuntimeCall(fn, value); // Cast the result back to the original type. - return CGF.Builder.CreateBitCast(call, origType); + return CGF.Builder.CreateBitCast(Inst, origType); } /// Produce the code to do a retain. Based on the type, calls one of: @@ -2493,7 +2498,7 @@ llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value, llvm::Type *resultType) { return emitObjCValueOperation(*this, value, resultType, CGM.getObjCEntrypoints().objc_alloc, - "objc_alloc"); + "objc_alloc", /*MayThrow=*/true); } /// Allocate the given objc object. @@ -2502,7 +2507,7 @@ llvm::Value *CodeGenFunction::EmitObjCAllocWithZone(llvm::Value *value, llvm::Type *resultType) { return emitObjCValueOperation(*this, value, resultType, CGM.getObjCEntrypoints().objc_allocWithZone, - "objc_allocWithZone"); + "objc_allocWithZone", /*MayThrow=*/true); } /// Produce the code to do a primitive release. @@ -2543,18 +2548,20 @@ void CodeGenFunction::emitARCIntrinsicUse(CodeGenFunction &CGF, Address addr, /// call i8* \@objc_autorelease(i8* %value) llvm::Value *CodeGenFunction::EmitObjCAutorelease(llvm::Value *value, llvm::Type *returnType) { - return emitObjCValueOperation(*this, value, returnType, - CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction, - "objc_autorelease"); + return emitObjCValueOperation( + *this, value, returnType, + CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction, + "objc_autorelease", /*MayThrow=*/false); } /// Retain the given object, with normal retain semantics. /// call i8* \@objc_retain(i8* %value) llvm::Value *CodeGenFunction::EmitObjCRetainNonBlock(llvm::Value *value, llvm::Type *returnType) { - return emitObjCValueOperation(*this, value, returnType, - CGM.getObjCEntrypoints().objc_retainRuntimeFunction, - "objc_retain"); + return emitObjCValueOperation( + *this, value, returnType, + CGM.getObjCEntrypoints().objc_retainRuntimeFunction, "objc_retain", + /*MayThrow=*/false); } /// Release the given object. |