[cfe-commits] r148325 - in /cfe/trunk: lib/CodeGen/CGException.cpp lib/CodeGen/CGObjCRuntime.cpp test/CodeGenObjC/arc-exceptions.m test/CodeGenObjCXX/arc-exceptions.mm

John McCall rjmccall at apple.com
Tue Jan 17 12:16:56 PST 2012


Author: rjmccall
Date: Tue Jan 17 14:16:56 2012
New Revision: 148325

URL: http://llvm.org/viewvc/llvm-project?rev=148325&view=rev
Log:
When initializing a catch variable in ARC, be sure to emit retains
or whatever else is required for the initialization instead of
assuming it can be done with a simple store.

Fixes PR11732.

Added:
    cfe/trunk/test/CodeGenObjC/arc-exceptions.m
    cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm
Modified:
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=148325&r1=148324&r2=148325&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Tue Jan 17 14:16:56 2012
@@ -984,8 +984,23 @@
     if (CatchType->hasPointerRepresentation()) {
       llvm::Value *CastExn =
         CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted");
-      CGF.Builder.CreateStore(CastExn, ParamAddr);
-      return;
+
+      switch (CatchType.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, ParamAddr);
+        return;
+
+      case Qualifiers::OCL_Weak:
+        CGF.EmitARCInitWeak(ParamAddr, CastExn);
+        return;
+      }
+      llvm_unreachable("bad ownership qualifier!");
     }
 
     // Otherwise, it returns a pointer into the exception object.

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp?rev=148325&r1=148324&r2=148325&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp Tue Jan 17 14:16:56 2012
@@ -246,7 +246,24 @@
       llvm::Value *CastExn = CGF.Builder.CreateBitCast(Exn, CatchType);
 
       CGF.EmitAutoVarDecl(*CatchParam);
-      CGF.Builder.CreateStore(CastExn, CGF.GetAddrOfLocalVar(CatchParam));
+
+      llvm::Value *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;
+      }
     }
 
     CGF.ObjCEHValueStack.push_back(Exn);

Added: cfe/trunk/test/CodeGenObjC/arc-exceptions.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-exceptions.m?rev=148325&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-exceptions.m (added)
+++ cfe/trunk/test/CodeGenObjC/arc-exceptions.m Tue Jan 17 14:16:56 2012
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fobjc-runtime-has-weak -o - %s | FileCheck %s
+
+ at class Ety;
+
+// These first two tests are all PR11732 / rdar://problem/10667070.
+
+void test0_helper(void);
+void test0(void) {
+  @try {
+    test0_helper();
+  } @catch (Ety *e) {
+  }
+}
+// CHECK: define void @test0()
+// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
+// CHECK-NEXT: invoke void @test0_helper()
+// CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) nounwind
+// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
+// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
+// CHECK-NEXT: [[T0:%.*]] = load [[ETY]]** [[E]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[ETY]]* [[T0]] to i8*
+// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
+// CHECK-NEXT: call void @objc_end_catch() nounwind
+
+void test1_helper(void);
+void test1(void) {
+  @try {
+    test1_helper();
+  } @catch (__weak Ety *e) {
+  }
+}
+// CHECK: define void @test1()
+// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
+// CHECK-NEXT: invoke void @test1_helper()
+// CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
+// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) nounwind
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) nounwind
+// CHECK-NEXT: call void @objc_end_catch() nounwind

Added: cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm?rev=148325&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm (added)
+++ cfe/trunk/test/CodeGenObjCXX/arc-exceptions.mm Tue Jan 17 14:16:56 2012
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-runtime-has-weak -o - %s | FileCheck %s
+
+ at class Ety;
+
+// These first four tests are all PR11732 / rdar://problem/10667070.
+
+void test0_helper(void);
+void test0(void) {
+  @try {
+    test0_helper();
+  } @catch (Ety *e) {
+  }
+}
+// CHECK: define void @_Z5test0v()
+// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
+// CHECK-NEXT: invoke void @_Z12test0_helperv()
+// CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) nounwind
+// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
+// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
+// CHECK-NEXT: [[T0:%.*]] = load [[ETY]]** [[E]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[ETY]]* [[T0]] to i8*
+// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
+// CHECK-NEXT: call void @objc_end_catch() nounwind
+
+void test1_helper(void);
+void test1(void) {
+  @try {
+    test1_helper();
+  } @catch (__weak Ety *e) {
+  }
+}
+// CHECK: define void @_Z5test1v()
+// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
+// CHECK-NEXT: invoke void @_Z12test1_helperv()
+// CHECK:      [[T0:%.*]] = call i8* @objc_begin_catch(
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
+// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) nounwind
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) nounwind
+// CHECK-NEXT: call void @objc_end_catch() nounwind
+
+void test2_helper(void);
+void test2(void) {
+  try {
+    test2_helper();
+  } catch (Ety *e) {
+  }
+}
+// CHECK: define void @_Z5test2v()
+// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
+// CHECK-NEXT: invoke void @_Z12test2_helperv()
+// CHECK:      [[T0:%.*]] = call i8* @__cxa_begin_catch(
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retain(i8* [[T2]]) nounwind
+// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[ETY]]*
+// CHECK-NEXT: store [[ETY]]* [[T4]], [[ETY]]** [[E]]
+// CHECK-NEXT: [[T0:%.*]] = load [[ETY]]** [[E]]
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[ETY]]* [[T0]] to i8*
+// CHECK-NEXT: call void @objc_release(i8* [[T1]]) nounwind
+// CHECK-NEXT: call void @__cxa_end_catch() nounwind
+
+void test3_helper(void);
+void test3(void) {
+  try {
+    test3_helper();
+  } catch (Ety * __weak e) {
+  }
+}
+// CHECK: define void @_Z5test3v()
+// CHECK:      [[E:%.*]] = alloca [[ETY:%.*]]*, align 8
+// CHECK-NEXT: invoke void @_Z12test3_helperv()
+// CHECK:      [[T0:%.*]] = call i8* @__cxa_begin_catch(
+// CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to [[ETY]]*
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[ETY]]** [[E]] to i8**
+// CHECK-NEXT: [[T3:%.*]] = bitcast [[ETY]]* [[T1]] to i8*
+// CHECK-NEXT: call i8* @objc_initWeak(i8** [[T2]], i8* [[T3]]) nounwind
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[ETY]]** [[E]] to i8**
+// CHECK-NEXT: call void @objc_destroyWeak(i8** [[T0]]) nounwind
+// CHECK-NEXT: call void @__cxa_end_catch() nounwind





More information about the cfe-commits mailing list