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