1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -O2 -o - %s | FileCheck %s
3 // <rdar://problem/7471679> [irgen] [eh] Exception code built with clang (x86_64) crashes
5 // Just check that we don't emit any dead blocks.
6 @interface NSArray @end
11 } @catch(NSArray *e) {
17 // CHECK: define void @f1()
19 extern void foo(void);
22 // CHECK: call void @objc_exception_try_enter
23 // CHECK-NEXT: getelementptr
24 // CHECK-NEXT: call i32 @_setjmp(
28 // CHECK: call void asm sideeffect "", "*m"
29 // CHECK-NEXT: call void @foo()
31 // CHECK-NEXT: call void @objc_exception_try_exit
33 // CHECK: call void asm sideeffect "", "=*m"
40 // Test that modifications to local variables are respected under
41 // optimization. rdar://problem/8160285
43 // CHECK: define i32 @f2()
45 extern void foo(void);
47 // CHECK: [[X:%.*]] = alloca i32
48 // CHECK: store i32 5, i32* [[X]]
52 // CHECK: [[SETJMP:%.*]] = call i32 @_setjmp
53 // CHECK-NEXT: [[CAUGHT:%.*]] = icmp eq i32 [[SETJMP]], 0
54 // CHECK-NEXT: br i1 [[CAUGHT]]
56 // If the optimizers ever figure out how to make this store 6,
58 // CHECK: [[T1:%.*]] = load i32* [[X]]
59 // CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], 1
60 // CHECK-NEXT: store i32 [[T2]], i32* [[X]]
62 // CHECK-NEXT: call void asm sideeffect "", "*m,*m"(i32* [[X]]
63 // CHECK-NEXT: call void @foo()
64 // CHECK-NEXT: call void @objc_exception_try_exit
65 // CHECK-NEXT: [[T:%.*]] = load i32* [[X]]
68 // Landing pad. Note that we elide the re-enter.
69 // CHECK: call void asm sideeffect "", "=*m,=*m"(i32* [[X]]
70 // CHECK-NEXT: call i8* @objc_exception_extract
71 // CHECK-NEXT: [[T1:%.*]] = load i32* [[X]]
72 // CHECK-NEXT: [[T2:%.*]] = add i32 [[T1]], -1
74 // This store is dead.
75 // CHECK-NEXT: store i32 [[T2]], i32* [[X]]
82 // Test that the cleanup destination is saved when entering a finally
83 // block. rdar://problem/8293901
84 // CHECK: define void @f3()
86 extern void f3_helper(int, int*);
88 // CHECK: [[X:%.*]] = alloca i32
89 // CHECK: store i32 0, i32* [[X]]
92 // CHECK: call void @objc_exception_try_enter(
93 // CHECK: call i32 @_setjmp
94 // CHECK-NEXT: icmp eq
98 // CHECK: call void @f3_helper(i32 0, i32* [[X]])
99 // CHECK: call void @objc_exception_try_exit(
102 // CHECK: [[DEST1:%.*]] = phi i32 [ 0, {{%.*}} ], [ 3, {{%.*}} ]
103 // CHECK: call void @objc_exception_try_enter
104 // CHECK: call i32 @_setjmp
106 // CHECK: call void @f3_helper(i32 1, i32* [[X]])
107 // CHECK: call void @objc_exception_try_exit(
110 // CHECK: [[DEST2:%.*]] = phi i32 [ 0, {{%.*}} ], [ 5, {{%.*}} ]
111 // CHECK: call void @f3_helper(i32 2, i32* [[X]])
114 // This loop is large enough to dissuade the optimizer from just
115 // duplicating the finally block.
116 while (x) f3_helper(3, &x);
118 // This is a switch or maybe some chained branches, but relying
119 // on a specific result from the optimizer is really unstable.
123 // This is a switch or maybe some chained branches, but relying
124 // on a specific result from the optimizer is really unstable.
128 // CHECK: call void @f3_helper(i32 4, i32* [[X]])
129 // CHECK-NEXT: ret void
133 // rdar://problem/8440970
135 extern void f4_help(int);
137 // CHECK: define void @f4()
138 // CHECK: [[EXNDATA:%.*]] = alloca [[EXNDATA_T:%.*]], align
139 // CHECK: call void @objc_exception_try_enter([[EXNDATA_T]]* [[EXNDATA]])
140 // CHECK: call i32 @_setjmp
142 // CHECK: call void @f4_help(i32 0)
145 // The finally cleanup has two threaded entrypoints after optimization:
147 // finally.no-call-exit: Predecessor is when the catch throws.
148 // CHECK: call i8* @objc_exception_extract([[EXNDATA_T]]* [[EXNDATA]])
149 // CHECK-NEXT: call void @f4_help(i32 2)
150 // CHECK-NEXT: br label
153 // finally.call-exit: Predecessors are the @try and @catch fallthroughs
154 // as well as the no-match case in the catch mechanism. The i1 is whether
155 // to rethrow and should be true only in the last case.
157 // CHECK-NEXT: phi i8*
158 // CHECK-NEXT: call void @objc_exception_try_exit([[EXNDATA_T]]* [[EXNDATA]])
159 // CHECK-NEXT: call void @f4_help(i32 2)
167 // CHECK: call i8* @objc_exception_extract([[EXNDATA_T]]* [[EXNDATA]])
168 // CHECK-NEXT: call void @objc_exception_try_enter([[EXNDATA_T]]* [[EXNDATA]])
169 // CHECK: call i32 @_setjmp
170 // -> next, finally.no-call-exit
171 // CHECK: call i32 @objc_exception_match
172 // -> finally.call-exit, match
173 } @catch (NSArray *a) {
175 // CHECK: call void @f4_help(i32 1)
176 // CHECK-NEXT: br label
177 // -> finally.call-exit
185 // CHECK-NEXT: call void @objc_exception_throw(i8*
186 // CHECK-NEXT: unreachable