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 6// rdar://12364847 7 8void foo(void); 9 10void test0(id obj) { 11 @synchronized(obj) { 12 foo(); 13 } 14} 15// CHECK-LABEL: define void @_Z5test0P11objc_object( 16// Enter the @synchronized block. 17// CHECK: call i32 @objc_sync_enter(i8* [[OBJ:%.*]]) 18// CHECK: call void @objc_exception_try_enter([[BUF_T:%.*]]* nonnull [[BUF:%.*]]) 19// CHECK-NEXT: [[T0:%.*]] = getelementptr [[BUF_T]], [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0 20// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* [[T0]]) 21// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 22// CHECK-NEXT: br i1 [[T2]], 23 24// Body. 25// CHECK: invoke void @_Z3foov() 26 27// Leave the @synchronized. The reload of obj here is unnecessary. 28// CHECK: call void @objc_exception_try_exit([[BUF_T]]* nonnull [[BUF]]) 29// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** 30// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]]) 31// CHECK-NEXT: ret void 32 33// Real EH cleanup. 34// CHECK: [[T0:%.*]] = landingpad 35// CHECK-NEXT: cleanup 36// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* nonnull [[BUF]]) 37// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** 38// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]]) 39// CHECK-NEXT: resume 40 41// ObjC EH "cleanup". 42// CHECK: [[T0:%.*]] = load i8*, i8** 43// CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T0]]) 44// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_exception_extract([[BUF_T]]* nonnull [[BUF]]) 45// CHECK-NEXT: call void @objc_exception_throw(i8* [[T0]]) 46// CHECK-NEXT: unreachable 47 48void test1(id obj, bool *failed) { 49 @try { 50 foo(); 51 } @catch (...) { 52 *failed = true; 53 } 54} 55// CHECK-LABEL: define void @_Z5test1P11objc_objectPb( 56// Enter the @try block. 57// CHECK: call void @objc_exception_try_enter([[BUF_T]]* nonnull [[BUF:%.*]]) 58// CHECK-NEXT: [[T0:%.*]] = getelementptr [[BUF_T]], [[BUF_T]]* [[BUF]], i32 0, i32 0, i32 0 59// CHECK-NEXT: [[T1:%.*]] = call i32 @_setjmp(i32* [[T0]]) 60// CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 61// CHECK-NEXT: br i1 [[T2]], 62 63// Body. 64// CHECK: invoke void @_Z3foov() 65 66// Leave the @try. 67// CHECK: call void @objc_exception_try_exit([[BUF_T]]* nonnull [[BUF]]) 68// CHECK-NEXT: br label 69// CHECK: ret void 70 71// Real EH cleanup. 72// CHECK: [[T0:%.*]] = landingpad 73// CHECK-NEXT: cleanup 74// CHECK-NEXT: call void @objc_exception_try_exit([[BUF_T]]* nonnull [[BUF]]) 75// CHECK-NEXT: resume 76 77// Catch handler. Reload of 'failed' address is unnecessary. 78// CHECK: [[T0:%.*]] = load i8*, i8** 79// CHECK-NEXT: store i8 1, i8* [[T0]], 80// CHECK-NEXT: br label 81