summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGObjC.cpp
diff options
context:
space:
mode:
authorErik Pilkington <erik.pilkington@gmail.com>2019-01-30 23:17:38 +0000
committerErik Pilkington <erik.pilkington@gmail.com>2019-01-30 23:17:38 +0000
commit1f7eda5aac1dd9abd754044ba9883d4e81cc08c0 (patch)
tree37768be81e35c7beb77ee208167d63785b6c15e3 /clang/lib/CodeGen/CGObjC.cpp
parent547a83b4ebd1cbbe90b092634bf1d909ded48555 (diff)
downloadbcm5719-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.cpp29
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.
OpenPOWER on IntegriCloud