1 // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \
2 // RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X64
3 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
4 // RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X86
5 // RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -fms-extensions -emit-llvm -o - \
6 // RUN: | FileCheck %s --check-prefix=X86-GNU
7 // RUN: %clang_cc1 %s -triple x86_64-pc-windows-gnu -fms-extensions -emit-llvm -o - \
8 // RUN: | FileCheck %s --check-prefix=X64-GNU
9
try_body(int numerator,int denominator,int * myres)10 void try_body(int numerator, int denominator, int *myres) {
11 *myres = numerator / denominator;
12 }
13 // CHECK-LABEL: define void @try_body(i32 %numerator, i32 %denominator, i32* %myres)
14 // CHECK: sdiv i32
15 // CHECK: store i32 %{{.*}}, i32*
16 // CHECK: ret void
17
safe_div(int numerator,int denominator,int * res)18 int safe_div(int numerator, int denominator, int *res) {
19 int myres = 0;
20 int success = 1;
21 __try {
22 try_body(numerator, denominator, &myres);
23 } __except (1) {
24 success = -42;
25 }
26 *res = myres;
27 return success;
28 }
29
30 // CHECK-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
31 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
32 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
33 // CHECK: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]]
34 // CHECK: to label %{{.*}} unwind label %[[catchpad:[^ ]*]]
35 //
36 // CHECK: [[catchpad]]
37 // X64: %[[padtoken:[^ ]*]] = catchpad within %{{[^ ]*}} [i8* null]
38 // X86: %[[padtoken:[^ ]*]] = catchpad within %{{[^ ]*}} [i8* bitcast (i32 ()* @"\01?filt$0@0@safe_div@@" to i8*)]
39 // CHECK-NEXT: catchret from %[[padtoken]] to label %[[except:[^ ]*]]
40 //
41 // CHECK: [[except]]
42 // CHECK: store i32 -42, i32* %[[success:[^ ]*]]
43 //
44 // CHECK: %[[res:[^ ]*]] = load i32, i32* %[[success]]
45 // CHECK: ret i32 %[[res]]
46
47 // 32-bit SEH needs this filter to save the exception code.
48 //
49 // X86-LABEL: define internal i32 @"\01?filt$0@0@safe_div@@"()
50 // X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1)
51 // X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[ebp]])
52 // X86: call i8* @llvm.localrecover(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[fp]], i32 0)
53 // X86: load i8*, i8**
54 // X86: load i32*, i32**
55 // X86: load i32, i32*
56 // X86: store i32 %{{.*}}, i32*
57 // X86: ret i32 1
58
59 // Mingw uses msvcrt, so it can also use _except_handler3.
60 // X86-GNU-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
61 // X86-GNU-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
62 // X64-GNU-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
63 // X64-GNU-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
64
65 void j(void);
66
filter_expr_capture(void)67 int filter_expr_capture(void) {
68 int r = 42;
69 __try {
70 j();
71 } __except(r = -1) {
72 r = 13;
73 }
74 return r;
75 }
76
77 // CHECK-LABEL: define i32 @filter_expr_capture()
78 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
79 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
80 // X64: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]])
81 // X86: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]], i32* %[[code:[^ ,]*]])
82 // CHECK: store i32 42, i32* %[[r]]
83 // CHECK: invoke void @j() #[[NOINLINE]]
84 //
85 // CHECK: catchpad within %{{[^ ]*}} [i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@filter_expr_capture@@" to i8*)]
86 // CHECK: store i32 13, i32* %[[r]]
87 //
88 // CHECK: %[[rv:[^ ]*]] = load i32, i32* %[[r]]
89 // CHECK: ret i32 %[[rv]]
90
91 // X64-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer)
92 // X64: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer)
93 // X64: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0)
94 //
95 // X86-LABEL: define internal i32 @"\01?filt$0@0@filter_expr_capture@@"()
96 // X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1)
97 // X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[ebp]])
98 // X86: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0)
99 //
100 // CHECK: store i32 -1, i32* %{{.*}}
101 // CHECK: ret i32 -1
102
nested_try(void)103 int nested_try(void) {
104 int r = 42;
105 __try {
106 __try {
107 j();
108 r = 0;
109 } __except(_exception_code() == 123) {
110 r = 123;
111 }
112 } __except(_exception_code() == 456) {
113 r = 456;
114 }
115 return r;
116 }
117 // CHECK-LABEL: define i32 @nested_try()
118 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
119 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
120 // CHECK: store i32 42, i32* %[[r:[^ ,]*]]
121 // CHECK: invoke void @j() #[[NOINLINE]]
122 // CHECK: to label %[[cont:[^ ]*]] unwind label %[[cswitch_inner:[^ ]*]]
123 //
124 // CHECK: [[cswitch_inner]]
125 // CHECK: %[[cs_inner:[^ ]*]] = catchswitch within none [label %[[cpad_inner:[^ ]*]]] unwind label %[[cswitch_outer:[^ ]*]]
126 //
127 // CHECK: [[cswitch_outer]]
128 // CHECK: %[[cs_outer:[^ ]*]] = catchswitch within none [label %[[cpad_outer:[^ ]*]]] unwind to caller
129 //
130 // CHECK: [[cpad_outer]]
131 // CHECK: catchpad within %{{[^ ]*}} [i8* bitcast (i32 ({{.*}})* @"\01?filt$0@0@nested_try@@" to i8*)]
132 // CHECK-NEXT: catchret {{.*}} to label %[[except_outer:[^ ]*]]
133 //
134 // CHECK: [[except_outer]]
135 // CHECK: store i32 456, i32* %[[r]]
136 // CHECK: br label %[[outer_try_cont:[^ ]*]]
137 //
138 // CHECK: [[outer_try_cont]]
139 // CHECK: %[[r_load:[^ ]*]] = load i32, i32* %[[r]]
140 // CHECK: ret i32 %[[r_load]]
141 //
142 // CHECK: [[cpad_inner]]
143 // CHECK: catchpad within %[[cs_inner]] [i8* bitcast (i32 ({{.*}})* @"\01?filt$1@0@nested_try@@" to i8*)]
144 // CHECK-NEXT: catchret {{.*}} to label %[[except_inner:[^ ]*]]
145 //
146 // CHECK: [[except_inner]]
147 // CHECK: store i32 123, i32* %[[r]]
148 // CHECK: br label %[[inner_try_cont:[^ ]*]]
149 //
150 // CHECK: [[inner_try_cont]]
151 // CHECK: br label %[[outer_try_cont]]
152 //
153 // CHECK: [[cont]]
154 // CHECK: store i32 0, i32* %[[r]]
155 // CHECK: br label %[[inner_try_cont]]
156 //
157 // CHECK-LABEL: define internal i32 @"\01?filt$0@0@nested_try@@"({{.*}})
158 // X86: call i8* @llvm.x86.seh.recoverfp({{.*}})
159 // CHECK: load i32*, i32**
160 // CHECK: load i32, i32*
161 // CHECK: icmp eq i32 %{{.*}}, 456
162 //
163 // CHECK-LABEL: define internal i32 @"\01?filt$1@0@nested_try@@"({{.*}})
164 // X86: call i8* @llvm.x86.seh.recoverfp({{.*}})
165 // CHECK: load i32*, i32**
166 // CHECK: load i32, i32*
167 // CHECK: icmp eq i32 %{{.*}}, 123
168
basic_finally(int g)169 int basic_finally(int g) {
170 __try {
171 j();
172 } __finally {
173 ++g;
174 }
175 return g;
176 }
177 // CHECK-LABEL: define i32 @basic_finally(i32 %g)
178 // X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
179 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
180 // CHECK: %[[g_addr:[^ ]*]] = alloca i32, align 4
181 // CHECK: call void (...) @llvm.localescape(i32* %[[g_addr]])
182 // CHECK: store i32 %g, i32* %[[g_addr]]
183 //
184 // CHECK: invoke void @j()
185 // CHECK: to label %[[cont:[^ ]*]] unwind label %[[cleanuppad:[^ ]*]]
186 //
187 // CHECK: [[cont]]
188 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
189 // CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
190 // CHECK: load i32, i32* %[[g_addr]], align 4
191 // CHECK: ret i32
192 //
193 // CHECK: [[cleanuppad]]
194 // CHECK: %[[padtoken:[^ ]*]] = cleanuppad within none []
195 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
196 // CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
197 // CHECK: cleanupret from %[[padtoken]] unwind to caller
198
199 // CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
200 // CHECK: call i8* @llvm.localrecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0)
201 // CHECK: load i32, i32* %{{.*}}, align 4
202 // CHECK: add nsw i32 %{{.*}}, 1
203 // CHECK: store i32 %{{.*}}, i32* %{{.*}}, align 4
204 // CHECK: ret void
205
206 int returns_int(void);
except_return(void)207 int except_return(void) {
208 __try {
209 return returns_int();
210 } __except(1) {
211 return 42;
212 }
213 }
214 // CHECK-LABEL: define i32 @except_return()
215 // CHECK: %[[tmp:[^ ]*]] = invoke i32 @returns_int()
216 // CHECK: to label %[[cont:[^ ]*]] unwind label %[[catchpad:[^ ]*]]
217 //
218 // CHECK: [[catchpad]]
219 // CHECK: catchpad
220 // CHECK: catchret
221 // CHECK: store i32 42, i32* %[[rv:[^ ]*]]
222 // CHECK: br label %[[retbb:[^ ]*]]
223 //
224 // CHECK: [[cont]]
225 // CHECK: store i32 %[[tmp]], i32* %[[rv]]
226 // CHECK: br label %[[retbb]]
227 //
228 // CHECK: [[retbb]]
229 // CHECK: %[[r:[^ ]*]] = load i32, i32* %[[rv]]
230 // CHECK: ret i32 %[[r]]
231
232
233 // PR 24751: don't assert if a variable is used twice in a __finally block.
234 // Also, make sure we don't do redundant work to capture/project it.
finally_capture_twice(int x)235 void finally_capture_twice(int x) {
236 __try {
237 } __finally {
238 int y = x;
239 int z = x;
240 }
241 }
242 //
243 // CHECK-LABEL: define void @finally_capture_twice(
244 // CHECK: [[X:%.*]] = alloca i32, align 4
245 // CHECK: call void (...) @llvm.localescape(i32* [[X]])
246 // CHECK-NEXT: store i32 {{.*}}, i32* [[X]], align 4
247 // CHECK-NEXT: [[LOCAL:%.*]] = call i8* @llvm.localaddress()
248 // CHECK-NEXT: call void [[FINALLY:@.*]](i8{{ zeroext | }}0, i8* [[LOCAL]])
249 // CHECK: define internal void [[FINALLY]](
250 // CHECK: [[LOCAL:%.*]] = call i8* @llvm.localrecover(
251 // CHECK: [[X:%.*]] = bitcast i8* [[LOCAL]] to i32*
252 // CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4
253 // CHECK-NEXT: [[Z:%.*]] = alloca i32, align 4
254 // CHECK-NEXT: store i8*
255 // CHECK-NEXT: store i8
256 // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[X]], align 4
257 // CHECK-NEXT: store i32 [[T0]], i32* [[Y]], align 4
258 // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[X]], align 4
259 // CHECK-NEXT: store i32 [[T0]], i32* [[Z]], align 4
260 // CHECK-NEXT: ret void
261
exception_code_in_except(void)262 int exception_code_in_except(void) {
263 __try {
264 try_body(0, 0, 0);
265 } __except(1) {
266 return _exception_code();
267 }
268 }
269
270 // CHECK-LABEL: define i32 @exception_code_in_except()
271 // CHECK: %[[ret_slot:[^ ]*]] = alloca i32
272 // CHECK: %[[code_slot:[^ ]*]] = alloca i32
273 // CHECK: invoke void @try_body(i32 0, i32 0, i32* null)
274 // CHECK: %[[pad:[^ ]*]] = catchpad
275 // CHECK: catchret from %[[pad]]
276 // X64: %[[code:[^ ]*]] = call i32 @llvm.eh.exceptioncode(token %[[pad]])
277 // X64: store i32 %[[code]], i32* %[[code_slot]]
278 // CHECK: %[[ret1:[^ ]*]] = load i32, i32* %[[code_slot]]
279 // CHECK: store i32 %[[ret1]], i32* %[[ret_slot]]
280 // CHECK: %[[ret2:[^ ]*]] = load i32, i32* %[[ret_slot]]
281 // CHECK: ret i32 %[[ret2]]
282
283 // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }
284