[CodeGenObjC] invoke objc_autorelease, objc_retain when necessary
authorErik Pilkington <erik.pilkington@gmail.com>
Wed, 15 May 2019 20:15:01 +0000 (20:15 +0000)
committerErik Pilkington <erik.pilkington@gmail.com>
Wed, 15 May 2019 20:15:01 +0000 (20:15 +0000)
Any of these methods can be overridden, so we need to invoke these functions.

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

llvm-svn: 360802

clang/lib/CodeGen/CGObjC.cpp
clang/test/CodeGenObjC/convert-messages-to-runtime-calls.m
clang/test/CodeGenObjC/objc-alloc-init.m

index 5b67565..8302c10 100644 (file)
@@ -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;
 
@@ -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);
@@ -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.
@@ -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.
@@ -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.
@@ -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.
index d1a9624..6a4edfd 100644 (file)
@@ -177,8 +177,8 @@ float test_cannot_message_return_float(C *c) {
 
 @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 {
@@ -186,3 +186,44 @@ void testException(NSObject *a) {
   } @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) {
+  }
+}
index a55a983..08a383d 100644 (file)
@@ -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;
@@ -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