[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGenObjCXX / arc-exceptions-seh.mm
blob0b697be54855d630d76a64117c32c30534bde009
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.
6 //
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.
11 void do_something();
12 void may_throw(id);
14 void try_catch_with_objc_intrinsic() {
15   id ex;
16   @try {
17     may_throw(ex);
18   } @catch (id ex_caught) {
19     do_something();
20     may_throw(ex_caught);
21   }
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:
32 // CHECK:         catch:
33 // CHECK-NEXT:      [[CATCHPAD:%[0-9]+]] = catchpad within [[CATCHSWITCH]]
34 // CHECK:           call
35 // CHECK:             @llvm.objc.retain
36 // CHECK:             [ "funclet"(token [[CATCHPAD]]) ]
37 // CHECK:           invoke
38 // CHECK:             do_something
39 // CHECK:             [ "funclet"(token [[CATCHPAD]]) ]
40 // CHECK:             unwind label %[[CLEANUP2:.*]]
41 // CHECK:           invoke
42 // CHECK:             may_throw
43 // CHECK:             [ "funclet"(token [[CATCHPAD]]) ]
44 // CHECK:             unwind label %[[CLEANUP2]]
45 // CHECK:           call
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]]
58 // CHECK:           call
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
68 // CHECK-O0:        call
69 // CHECK-O0:          @llvm.objc.storeStrong
70 // CHECK-O0:          [ "funclet"(token [[CLEANUPPAD1]]) ]
71 // CHECK-O0:        cleanupret from [[CLEANUPPAD1]] unwind to caller