Skip to content

Commit

Permalink
[CodeGenObjC] invoke objc_autorelease, objc_retain when necessary
Browse files Browse the repository at this point in the history
Any of these methods can be overridden, so we need to invoke these functions.

Differential revision: https://reviews.llvm.org/D61957

llvm-svn: 360802
  • Loading branch information
epilk committed May 15, 2019
1 parent 11b515a commit f6c645f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 18 deletions.
19 changes: 7 additions & 12 deletions clang/lib/CodeGen/CGObjC.cpp
Expand Up @@ -2059,7 +2059,7 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
llvm::Value *value,
llvm::Type *returnType,
llvm::FunctionCallee &fn,
StringRef fnName, bool MayThrow) {
StringRef fnName) {
if (isa<llvm::ConstantPointerNull>(value))
return value;

Expand All @@ -2079,11 +2079,7 @@ static llvm::Value *emitObjCValueOperation(CodeGenFunction &CGF,
value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);

// Call the function.
llvm::CallBase *Inst = nullptr;
if (MayThrow)
Inst = CGF.EmitCallOrInvoke(fn, value);
else
Inst = CGF.EmitNounwindRuntimeCall(fn, value);
llvm::CallBase *Inst = CGF.EmitCallOrInvoke(fn, value);

// Cast the result back to the original type.
return CGF.Builder.CreateBitCast(Inst, origType);
Expand Down Expand Up @@ -2536,7 +2532,7 @@ llvm::Value *CodeGenFunction::EmitObjCAlloc(llvm::Value *value,
llvm::Type *resultType) {
return emitObjCValueOperation(*this, value, resultType,
CGM.getObjCEntrypoints().objc_alloc,
"objc_alloc", /*MayThrow=*/true);
"objc_alloc");
}

/// Allocate the given objc object.
Expand All @@ -2545,14 +2541,14 @@ llvm::Value *CodeGenFunction::EmitObjCAllocWithZone(llvm::Value *value,
llvm::Type *resultType) {
return emitObjCValueOperation(*this, value, resultType,
CGM.getObjCEntrypoints().objc_allocWithZone,
"objc_allocWithZone", /*MayThrow=*/true);
"objc_allocWithZone");
}

llvm::Value *CodeGenFunction::EmitObjCAllocInit(llvm::Value *value,
llvm::Type *resultType) {
return emitObjCValueOperation(*this, value, resultType,
CGM.getObjCEntrypoints().objc_alloc_init,
"objc_alloc_init", /*MayThrow=*/true);
"objc_alloc_init");
}

/// Produce the code to do a primitive release.
Expand Down Expand Up @@ -2596,7 +2592,7 @@ llvm::Value *CodeGenFunction::EmitObjCAutorelease(llvm::Value *value,
return emitObjCValueOperation(
*this, value, returnType,
CGM.getObjCEntrypoints().objc_autoreleaseRuntimeFunction,
"objc_autorelease", /*MayThrow=*/false);
"objc_autorelease");
}

/// Retain the given object, with normal retain semantics.
Expand All @@ -2605,8 +2601,7 @@ llvm::Value *CodeGenFunction::EmitObjCRetainNonBlock(llvm::Value *value,
llvm::Type *returnType) {
return emitObjCValueOperation(
*this, value, returnType,
CGM.getObjCEntrypoints().objc_retainRuntimeFunction, "objc_retain",
/*MayThrow=*/false);
CGM.getObjCEntrypoints().objc_retainRuntimeFunction, "objc_retain");
}

/// Release the given object.
Expand Down
45 changes: 43 additions & 2 deletions clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
Expand Up @@ -177,12 +177,53 @@ - (void)retain_super {

@class Ety;

// CHECK-LABEL: define {{.*}}void @testException
void testException(NSObject *a) {
// CHECK-LABEL: define {{.*}}void @testException_release
void testException_release(NSObject *a) {
// MSGS: {{invoke.*@objc_msgSend}}
// CALLS: invoke{{.*}}void @objc_release(i8* %
@try {
[a release];
} @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) {
}
}
15 changes: 11 additions & 4 deletions clang/test/CodeGenObjC/objc-alloc-init.m
@@ -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-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-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=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.3 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=NOT_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-exceptions -fexceptions -fobjc-runtime=ios-12.1 -emit-llvm -O0 -o - | FileCheck %s --check-prefix=NOT_OPTIMIZED --check-prefix=EITHER

@interface X
+(X *)alloc;
Expand All @@ -12,6 +12,13 @@ void f() {
[[X alloc] init];
// OPTIMIZED: call i8* @objc_alloc_init(
// 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
Expand Down

0 comments on commit f6c645f

Please sign in to comment.