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