1 // RUN: %clang_cc1 -O0 -triple x86_64-pc-windows-msvc -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fobjc-arc-exceptions -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-O0
2 // RUN: %clang_cc1 -O2 -triple x86_64-pc-windows-msvc -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fobjc-arc-exceptions -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-O2
4 // WinEH requires funclet tokens on nounwind intrinsics if they can lower to
5 // regular function calls in the course of IR transformations.
7 // This is the case for ObjC ARC runtime intrinsics. Test that clang emits the
8 // funclet tokens for llvm.objc.* calls inside catch- and cleanup-pads and that
9 // they refer to their pad's SSA value.
14 void try_catch_with_objc_intrinsic() {
18 } @catch (id ex_caught) {
24 // CHECK-LABEL: try_catch_with_objc_intrinsic
26 // CHECK: catch.dispatch:
27 // CHECK-NEXT: [[CATCHSWITCH:%[0-9]+]] = catchswitch within none [label %catch]
28 // CHECK-O0: unwind label %[[CLEANUP1:.*]]
29 // CHECK-O2: unwind to caller
31 // All calls within a catchpad must have funclet tokens that refer to it:
33 // CHECK-NEXT: [[CATCHPAD:%[0-9]+]] = catchpad within [[CATCHSWITCH]]
35 // CHECK: @llvm.objc.retain
36 // CHECK: [ "funclet"(token [[CATCHPAD]]) ]
38 // CHECK: do_something
39 // CHECK: [ "funclet"(token [[CATCHPAD]]) ]
40 // CHECK: unwind label %[[CLEANUP2:.*]]
43 // CHECK: [ "funclet"(token [[CATCHPAD]]) ]
44 // CHECK: unwind label %[[CLEANUP2]]
46 // CHECK-O0: @llvm.objc.storeStrong
47 // CHECK-O2: @llvm.objc.release
48 // CHECK: [ "funclet"(token [[CATCHPAD]]) ]
49 // CHECK-O0: catchret from [[CATCHPAD]] to label %catchret.dest
50 // CHECK-O2: catchret from [[CATCHPAD]] to label %eh.cont
52 // In debug mode, this block exists and it's empty:
53 // CHECK-O0: catchret.dest:
54 // CHECK-O0-NEXT: br label %eh.cont
56 // CHECK: [[CLEANUP2]]:
57 // CHECK-NEXT: [[CLEANUPPAD2:%[0-9]+]] = cleanuppad within [[CATCHPAD]]
59 // CHECK-O0: @llvm.objc.storeStrong
60 // CHECK-O2: @llvm.objc.release
61 // CHECK: [ "funclet"(token [[CLEANUPPAD2]]) ]
62 // CHECK: cleanupret from [[CLEANUPPAD2]]
63 // CHECK-O0: unwind label %[[CLEANUP1]]
64 // CHECK-O2: unwind to caller
66 // CHECK-O0: [[CLEANUP1]]:
67 // CHECK-O0-NEXT: [[CLEANUPPAD1:%[0-9]+]] = cleanuppad within none
69 // CHECK-O0: @llvm.objc.storeStrong
70 // CHECK-O0: [ "funclet"(token [[CLEANUPPAD1]]) ]
71 // CHECK-O0: cleanupret from [[CLEANUPPAD1]] unwind to caller