r251677 - Initialize @catch variables correctly in fragile-runtime ARC.

John McCall via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 29 17:56:03 PDT 2015


Author: rjmccall
Date: Thu Oct 29 19:56:02 2015
New Revision: 251677

URL: http://llvm.org/viewvc/llvm-project?rev=251677&view=rev
Log:
Initialize @catch variables correctly in fragile-runtime ARC.

Modified:
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
    cfe/trunk/lib/CodeGen/CGObjCRuntime.h
    cfe/trunk/test/CodeGenObjC/fragile-arc.m

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=251677&r1=251676&r2=251677&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Thu Oct 29 19:56:02 2015
@@ -4135,7 +4135,7 @@ void CGObjCMac::EmitTryOrSynchronizedStm
           assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
 
           // These types work out because ConvertType(id) == i8*.
-          CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
+          EmitInitOfCatchParam(CGF, Caught, CatchParam);
         }
 
         CGF.EmitStmt(CatchStmt->getCatchBody());
@@ -4182,7 +4182,7 @@ void CGObjCMac::EmitTryOrSynchronizedStm
       llvm::Value *Tmp =
         CGF.Builder.CreateBitCast(Caught,
                                   CGF.ConvertType(CatchParam->getType()));
-      CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
+      EmitInitOfCatchParam(CGF, Tmp, CatchParam);
 
       CGF.EmitStmt(CatchStmt->getCatchBody());
 

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp?rev=251677&r1=251676&r2=251677&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp Thu Oct 29 19:56:02 2015
@@ -256,24 +256,7 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
       llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);
 
       CGF.EmitAutoVarDecl(*CatchParam);
-
-      Address CatchParamAddr = CGF.GetAddrOfLocalVar(CatchParam);
-
-      switch (CatchParam->getType().getQualifiers().getObjCLifetime()) {
-      case Qualifiers::OCL_Strong:
-        CastExn = CGF.EmitARCRetainNonBlock(CastExn);
-        // fallthrough
-
-      case Qualifiers::OCL_None:
-      case Qualifiers::OCL_ExplicitNone:
-      case Qualifiers::OCL_Autoreleasing:
-        CGF.Builder.CreateStore(CastExn, CatchParamAddr);
-        break;
-
-      case Qualifiers::OCL_Weak:
-        CGF.EmitARCInitWeak(CatchParamAddr, CastExn);
-        break;
-      }
+      EmitInitOfCatchParam(CGF, CastExn, CatchParam);
     }
 
     CGF.ObjCEHValueStack.push_back(Exn);
@@ -297,6 +280,30 @@ void CGObjCRuntime::EmitTryCatchStmt(Cod
     CGF.EmitBlock(Cont.getBlock());
 }
 
+void CGObjCRuntime::EmitInitOfCatchParam(CodeGenFunction &CGF,
+                                         llvm::Value *exn,
+                                         const VarDecl *paramDecl) {
+
+  Address paramAddr = CGF.GetAddrOfLocalVar(paramDecl);
+
+  switch (paramDecl->getType().getQualifiers().getObjCLifetime()) {
+  case Qualifiers::OCL_Strong:
+    exn = CGF.EmitARCRetainNonBlock(exn);
+    // fallthrough
+
+  case Qualifiers::OCL_None:
+  case Qualifiers::OCL_ExplicitNone:
+  case Qualifiers::OCL_Autoreleasing:
+    CGF.Builder.CreateStore(exn, paramAddr);
+    return;
+
+  case Qualifiers::OCL_Weak:
+    CGF.EmitARCInitWeak(paramAddr, exn);
+    return;
+  }
+  llvm_unreachable("invalid ownership qualifier");
+}
+
 namespace {
   struct CallSyncExit final : EHScopeStack::Cleanup {
     llvm::Value *SyncExitFn;

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=251677&r1=251676&r2=251677&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Thu Oct 29 19:56:02 2015
@@ -100,6 +100,10 @@ protected:
                         llvm::Constant *beginCatchFn,
                         llvm::Constant *endCatchFn,
                         llvm::Constant *exceptionRethrowFn);
+
+  void EmitInitOfCatchParam(CodeGenFunction &CGF, llvm::Value *exn,
+                            const VarDecl *paramDecl);
+
   /// Emits an \@synchronize() statement, using the \p syncEnterFn and
   /// \p syncExitFn arguments as the functions called to lock and unlock
   /// the object.  This function can be called by subclasses that use

Modified: cfe/trunk/test/CodeGenObjC/fragile-arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/fragile-arc.m?rev=251677&r1=251676&r2=251677&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/fragile-arc.m (original)
+++ cfe/trunk/test/CodeGenObjC/fragile-arc.m Thu Oct 29 19:56:02 2015
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s -check-prefix=GLOBALS
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-exceptions -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-exceptions -fobjc-runtime=macosx-fragile-10.10 -o - %s | FileCheck %s -check-prefix=GLOBALS
 
 @class Opaque;
 
@@ -136,3 +136,40 @@ void testBlockLayoutStrong(id x) {
 void testBlockLayoutWeak(__weak id x) {
   useBlock(^{ (void) x; });
 }
+
+// CHECK-LABEL: define void @testCatch()
+// CHECK: [[X:%.*]] = alloca [[A:%.*]]*, align 4
+// CHECK: [[Y:%.*]] = alloca i8*, align 4
+// CHECK: call void @objc_exception_try_enter
+// CHECK: br i1
+// CHECK: call void @checkpoint(i32 0)
+// CHECK: call void @objc_exception_try_exit
+// CHECK: br label
+// CHECK: call void @checkpoint(i32 3)
+// CHECK: [[EXN:%.*]] = call i8* @objc_exception_extract
+// CHECK: call i32 @objc_exception_match(
+// CHECK: br i1
+// CHECK: [[T0:%.*]] = bitcast i8* [[EXN]] to [[A]]*
+// CHECK: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
+// CHECK: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
+// CHECK: store [[A]]* [[T3]], [[A]]** [[X]]
+// CHECK: call void @checkpoint(i32 1)
+// CHECK: [[T0:%.*]] = bitcast [[A]]** [[X]] to i8**
+// CHECK: call void @objc_storeStrong(i8** [[T0]], i8* null)
+// CHECK: br label
+// CHECK: [[T0:%.*]] = call i8* @objc_retain(i8* [[EXN]])
+// CHECK: store i8* [[T0]], i8** [[Y]]
+// CHECK: call void @checkpoint(i32 2)
+// CHECK: call void @objc_storeStrong(i8** [[Y]], i8* null)
+extern void checkpoint(int n);
+void testCatch() {
+  @try {
+    checkpoint(0);
+  } @catch (A *x) {
+    checkpoint(1);
+  } @catch (id y) {
+    checkpoint(2);
+  }
+  checkpoint(3);
+}




More information about the cfe-commits mailing list