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