forked from OSchip/llvm-project
[CodeGenObjC] invoke objc_autorelease, objc_retain when necessary
Any of these methods can be overridden, so we need to invoke these functions. Differential revision: https://reviews.llvm.org/D61957 llvm-svn: 360802
This commit is contained in:
parent
11b515ac0a
commit
f6c645f9fd
|
@ -2059,7 +2059,7 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
|
||||||
llvm::Value *value,
|
llvm::Value *value,
|
||||||
llvm::Type *returnType,
|
llvm::Type *returnType,
|
||||||
llvm::FunctionCallee &fn,
|
llvm::FunctionCallee &fn,
|
||||||
StringRef fnName, bool MayThrow) {
|
StringRef fnName) {
|
||||||
if (isa<llvm::ConstantPointerNull>(value))
|
if (isa<llvm::ConstantPointerNull>(value))
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
|
@ -2079,11 +2079,7 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
|
||||||
value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
|
value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
|
||||||
|
|
||||||
// Call the function.
|
// Call the function.
|
||||||
llvm::CallBase *Inst = nullptr;
|
llvm::CallBase *Inst = CGF.EmitCallOrInvoke(fn, value);
|
||||||
if (MayThrow)
|
|
||||||
Inst = CGF.EmitCallOrInvoke(fn, value);
|
|
||||||
else
|
|
||||||
Inst = CGF.EmitNounwindRuntimeCall(fn, value);
|
|
||||||
|
|
||||||
// Cast the result back to the original type.
|
// Cast the result back to the original type.
|
||||||
return CGF.Builder.CreateBitCast(Inst, origType);
|
return CGF.Builder.CreateBitCast(Inst, origType);
|
||||||
|
@ -2536,7 +2532,7 @@ llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value,
|
||||||
llvm::Type *resultType) {
|
llvm::Type *resultType) {
|
||||||
return emitObjCValueOperation(*this, value, resultType,
|
return emitObjCValueOperation(*this, value, resultType,
|
||||||
CGM.getObjCEntrypoints().objc_alloc,
|
CGM.getObjCEntrypoints().objc_alloc,
|
||||||
"objc_alloc", /*MayThrow=*/true);
|
"objc_alloc");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate the given objc object.
|
/// Allocate the given objc object.
|
||||||
|
@ -2545,14 +2541,14 @@ llvm::Value *CodeGenFunction::EmitObjCAllocWithZone(llvm::Value *value,
|
||||||
llvm::Type *resultType) {
|
llvm::Type *resultType) {
|
||||||
return emitObjCValueOperation(*this, value, resultType,
|
return emitObjCValueOperation(*this, value, resultType,
|
||||||
CGM.getObjCEntrypoints().objc_allocWithZone,
|
CGM.getObjCEntrypoints().objc_allocWithZone,
|
||||||
"objc_allocWithZone", /*MayThrow=*/true);
|
"objc_allocWithZone");
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value *CodeGenFunction::EmitObjCAllocInit(llvm::Value *value,
|
llvm::Value *CodeGenFunction::EmitObjCAllocInit(llvm::Value *value,
|
||||||
llvm::Type *resultType) {
|
llvm::Type *resultType) {
|
||||||
return emitObjCValueOperation(*this, value, resultType,
|
return emitObjCValueOperation(*this, value, resultType,
|
||||||
CGM.getObjCEntrypoints().objc_alloc_init,
|
CGM.getObjCEntrypoints().objc_alloc_init,
|
||||||
"objc_alloc_init", /*MayThrow=*/true);
|
"objc_alloc_init");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Produce the code to do a primitive release.
|
/// Produce the code to do a primitive release.
|
||||||
|
@ -2596,7 +2592,7 @@ llvm::Value *CodeGenFunction::EmitObjCAutorelease(llvm::Value *value,
|
||||||
return emitObjCValueOperation(
|
return emitObjCValueOperation(
|
||||||
*this, value, returnType,
|
*this, value, returnType,
|
||||||
CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction,
|
CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction,
|
||||||
"objc_autorelease", /*MayThrow=*/false);
|
"objc_autorelease");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retain the given object, with normal retain semantics.
|
/// Retain the given object, with normal retain semantics.
|
||||||
|
@ -2605,8 +2601,7 @@ llvm::Value *CodeGenFunction::EmitObjCRetainNonBlock(llvm::Value *value,
|
||||||
llvm::Type *returnType) {
|
llvm::Type *returnType) {
|
||||||
return emitObjCValueOperation(
|
return emitObjCValueOperation(
|
||||||
*this, value, returnType,
|
*this, value, returnType,
|
||||||
CGM.getObjCEntrypoints().objc_retainRuntimeFunction, "objc_retain",
|
CGM.getObjCEntrypoints().objc_retainRuntimeFunction, "objc_retain");
|
||||||
/*MayThrow=*/false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Release the given object.
|
/// Release the given object.
|
||||||
|
|
|
@ -177,8 +177,8 @@ float test_cannot_message_return_float(C *c) {
|
||||||
|
|
||||||
@class Ety;
|
@class Ety;
|
||||||
|
|
||||||
// CHECK-LABEL: define {{.*}}void @testException
|
// CHECK-LABEL: define {{.*}}void @testException_release
|
||||||
void testException(NSObject *a) {
|
void testException_release(NSObject *a) {
|
||||||
// MSGS: {{invoke.*@objc_msgSend}}
|
// MSGS: {{invoke.*@objc_msgSend}}
|
||||||
// CALLS: invoke{{.*}}void @objc_release(i8* %
|
// CALLS: invoke{{.*}}void @objc_release(i8* %
|
||||||
@try {
|
@try {
|
||||||
|
@ -186,3 +186,44 @@ void testException(NSObject *a) {
|
||||||
} @catch (Ety *e) {
|
} @catch (Ety *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: define {{.*}}void @testException_autorelease
|
||||||
|
void testException_autorelease(NSObject *a) {
|
||||||
|
@try {
|
||||||
|
// MSGS: {{invoke.*@objc_msgSend}}
|
||||||
|
// CALLS: invoke{{.*}}objc_autorelease(i8* %
|
||||||
|
[a autorelease];
|
||||||
|
} @catch (Ety *e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: define {{.*}}void @testException_retain
|
||||||
|
void testException_retain(NSObject *a) {
|
||||||
|
@try {
|
||||||
|
// MSGS: {{invoke.*@objc_msgSend}}
|
||||||
|
// CALLS: invoke{{.*}}@objc_retain(i8* %
|
||||||
|
[a retain];
|
||||||
|
} @catch (Ety *e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CHECK-LABEL: define {{.*}}void @testException_alloc(
|
||||||
|
void testException_alloc() {
|
||||||
|
@try {
|
||||||
|
// MSGS: {{invoke.*@objc_msgSend}}
|
||||||
|
// CALLS: invoke{{.*}}@objc_alloc(i8* %
|
||||||
|
[A alloc];
|
||||||
|
} @catch (Ety *e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: define {{.*}}void @testException_allocWithZone
|
||||||
|
void testException_allocWithZone() {
|
||||||
|
@try {
|
||||||
|
// MSGS: {{invoke.*@objc_msgSend}}
|
||||||
|
// CALLS: invoke{{.*}}@objc_allocWithZone(i8* %
|
||||||
|
[A allocWithZone:nil];
|
||||||
|
} @catch (Ety *e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// RUN: %clang_cc1 %s -fobjc-runtime=macosx-10.14.4 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=OPTIMIZED --check-prefix=EITHER
|
// RUN: %clang_cc1 %s -fobjc-exceptions -fexceptions -fobjc-runtime=macosx-10.14.4 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=OPTIMIZED --check-prefix=EITHER
|
||||||
// RUN: %clang_cc1 %s -fobjc-runtime=macosx-10.14.3 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=NOT_OPTIMIZED --check-prefix=EITHER
|
// RUN: %clang_cc1 %s -fobjc-exceptions -fexceptions -fobjc-runtime=macosx-10.14.3 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=NOT_OPTIMIZED --check-prefix=EITHER
|
||||||
// RUN: %clang_cc1 %s -fobjc-runtime=ios-12.2 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=OPTIMIZED --check-prefix=EITHER
|
// RUN: %clang_cc1 %s -fobjc-exceptions -fexceptions -fobjc-runtime=ios-12.2 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=OPTIMIZED --check-prefix=EITHER
|
||||||
// RUN: %clang_cc1 %s -fobjc-runtime=ios-12.1 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=NOT_OPTIMIZED --check-prefix=EITHER
|
// RUN: %clang_cc1 %s -fobjc-exceptions -fexceptions -fobjc-runtime=ios-12.1 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=NOT_OPTIMIZED --check-prefix=EITHER
|
||||||
|
|
||||||
@interface X
|
@interface X
|
||||||
+(X *)alloc;
|
+(X *)alloc;
|
||||||
|
@ -12,6 +12,13 @@ void f() {
|
||||||
[[X alloc] init];
|
[[X alloc] init];
|
||||||
// OPTIMIZED: call i8* @objc_alloc_init(
|
// OPTIMIZED: call i8* @objc_alloc_init(
|
||||||
// NOT_OPTIMIZED: call i8* @objc_alloc(
|
// NOT_OPTIMIZED: call i8* @objc_alloc(
|
||||||
|
|
||||||
|
@try {
|
||||||
|
[[X alloc] init];
|
||||||
|
} @catch (X *x) {
|
||||||
|
}
|
||||||
|
// OPTIMIZED: invoke i8* @objc_alloc_init(
|
||||||
|
// NOT_OPTIMIZED: invoke i8* @objc_alloc(
|
||||||
}
|
}
|
||||||
|
|
||||||
@interface Y : X
|
@interface Y : X
|
||||||
|
|
Loading…
Reference in New Issue