xref: /llvm-project/clang/test/CodeGenObjCXX/exceptions-legacy.mm (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1// RUN: %clang_cc1 -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -fexceptions -fobjc-exceptions -O2 -o - %s | FileCheck %s
2
3// Test we maintain at least a basic amount of interoperation between
4// ObjC and C++ exceptions in the legacy runtime.
5
6void foo(void);
7
8void test0(id obj) {
9  @synchronized(obj) {
10    foo();
11  }
12}
13// CHECK-LABEL:    define{{.*}} void @_Z5test0P11objc_object(
14//   Enter the @synchronized block.
15// CHECK:      call i32 @objc_sync_enter(ptr [[OBJ:%.*]])
16// CHECK:      call void @objc_exception_try_enter(ptr nonnull [[BUF:%.*]])
17// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(ptr nonnull [[BUF]])
18// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
19// CHECK-NEXT: br i1 [[T2]],
20
21//   Body.
22// CHECK:      invoke void @_Z3foov()
23
24//   Leave the @synchronized.  The reload of obj here is unnecessary.
25// CHECK:      call void @objc_exception_try_exit(ptr nonnull [[BUF]])
26// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
27// CHECK-NEXT: call i32 @objc_sync_exit(ptr [[T0]])
28// CHECK-NEXT: ret void
29
30//   Real EH cleanup.
31// CHECK:      [[T0:%.*]] = landingpad
32// CHECK-NEXT:    cleanup
33// CHECK-NEXT: call void @objc_exception_try_exit(ptr nonnull [[BUF]])
34// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr
35// CHECK-NEXT: call i32 @objc_sync_exit(ptr [[T0]])
36// CHECK-NEXT: resume
37
38//   ObjC EH "cleanup".
39// CHECK:      [[T0:%.*]] = load ptr, ptr
40// CHECK-NEXT: call i32 @objc_sync_exit(ptr [[T0]])
41// CHECK-NEXT: [[T0:%.*]] = call ptr @objc_exception_extract(ptr nonnull [[BUF]])
42// CHECK-NEXT: call void @objc_exception_throw(ptr [[T0]])
43// CHECK-NEXT: unreachable
44
45void test1(id obj, bool *failed) {
46  @try {
47    foo();
48  } @catch (...) {
49    *failed = true;
50  }
51}
52// CHECK-LABEL:    define{{.*}} void @_Z5test1P11objc_objectPb(
53//   Enter the @try block.
54// CHECK:      call void @objc_exception_try_enter(ptr nonnull [[BUF:%.*]])
55// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(ptr nonnull [[BUF]])
56// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
57// CHECK-NEXT: br i1 [[T2]],
58
59//   Body.
60// CHECK:      invoke void @_Z3foov()
61
62//   Catch handler.  Reload of 'failed' address is unnecessary.
63// CHECK:      [[T0:%.*]] = load ptr, ptr
64// CHECK-NEXT: store i8 1, ptr [[T0]],
65// CHECK-NEXT: br label
66
67//   Leave the @try.
68// CHECK:      call void @objc_exception_try_exit(ptr nonnull [[BUF]])
69// CHECK-NEXT: br label
70// CHECK:      ret void
71
72
73//   Real EH cleanup.
74// CHECK:      [[T0:%.*]] = landingpad
75// CHECK-NEXT:    cleanup
76// CHECK-NEXT: call void @objc_exception_try_exit(ptr nonnull [[BUF]])
77// CHECK-NEXT: resume
78
79