summaryrefslogtreecommitdiffstats
path: root/test/CodeGenObjC/exceptions.m
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenObjC/exceptions.m')
-rw-r--r--test/CodeGenObjC/exceptions.m62
1 files changed, 57 insertions, 5 deletions
diff --git a/test/CodeGenObjC/exceptions.m b/test/CodeGenObjC/exceptions.m
index b431e37..31805cb 100644
--- a/test/CodeGenObjC/exceptions.m
+++ b/test/CodeGenObjC/exceptions.m
@@ -29,10 +29,8 @@ void f1() {
// CHECK-NEXT: call void @foo()
foo();
// CHECK-NEXT: call void @objc_exception_try_exit
- // CHECK-NEXT: ret void
// CHECK: call void asm sideeffect "", "=*m"
- // CHECK-NEXT: ret void
} @finally {
break;
}
@@ -65,7 +63,6 @@ int f2() {
// CHECK-NEXT: call void @foo()
// CHECK-NEXT: call void @objc_exception_try_exit
// CHECK-NEXT: [[T:%.*]] = load i32* [[X]]
- // CHECK-NEXT: ret i32 [[T]]
foo();
} @catch (id) {
// Landing pad. Note that we elide the re-enter.
@@ -76,10 +73,9 @@ int f2() {
// This store is dead.
// CHECK-NEXT: store i32 [[T2]], i32* [[X]]
-
- // CHECK-NEXT: ret i32 [[T2]]
x--;
}
+
return x;
}
@@ -133,3 +129,59 @@ void f3() {
// CHECK-NEXT: ret void
f3_helper(4, &x);
}
+
+// rdar://problem/8440970
+void f4() {
+ extern void f4_help(int);
+
+ // CHECK: define void @f4()
+ // CHECK: [[EXNDATA:%.*]] = alloca [[EXNDATA_T:%.*]], align
+ // CHECK: call void @objc_exception_try_enter([[EXNDATA_T]]* [[EXNDATA]])
+ // CHECK: call i32 @_setjmp
+ @try {
+ // CHECK: call void @f4_help(i32 0)
+ f4_help(0);
+
+ // The finally cleanup has two threaded entrypoints after optimization:
+
+ // finally.no-call-exit: Predecessor is when the catch throws.
+ // CHECK: call i8* @objc_exception_extract([[EXNDATA_T]]* [[EXNDATA]])
+ // CHECK-NEXT: call void @f4_help(i32 2)
+ // CHECK-NEXT: br label
+ // -> rethrow
+
+ // finally.call-exit: Predecessors are the @try and @catch fallthroughs
+ // as well as the no-match case in the catch mechanism. The i1 is whether
+ // to rethrow and should be true only in the last case.
+ // CHECK: phi i1
+ // CHECK-NEXT: phi i8*
+ // CHECK-NEXT: call void @objc_exception_try_exit([[EXNDATA_T]]* [[EXNDATA]])
+ // CHECK-NEXT: call void @f4_help(i32 2)
+ // CHECK-NEXT: br i1
+ // -> ret, rethrow
+
+ // ret:
+ // CHECK: ret void
+
+ // Catch mechanism:
+ // CHECK: call i8* @objc_exception_extract([[EXNDATA_T]]* [[EXNDATA]])
+ // CHECK-NEXT: call void @objc_exception_try_enter([[EXNDATA_T]]* [[EXNDATA]])
+ // CHECK: call i32 @_setjmp
+ // -> next, finally.no-call-exit
+ // CHECK: call i32 @objc_exception_match
+ // -> finally.call-exit, match
+ } @catch (NSArray *a) {
+ // match:
+ // CHECK: call void @f4_help(i32 1)
+ // CHECK-NEXT: br label
+ // -> finally.call-exit
+ f4_help(1);
+ } @finally {
+ f4_help(2);
+ }
+
+ // rethrow:
+ // CHECK: phi i8*
+ // CHECK-NEXT: call void @objc_exception_throw(i8*
+ // CHECK-NEXT: unreachable
+}
OpenPOWER on IntegriCloud