1 // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | opt -instnamer -S | FileCheck %s
2 
3 void g(void);
4 
5 //////////////////////////////////////////////////////////////////////////////
6 // __leave with __except
7 
8 // Nothing in the __try block can trap, so __try.cont isn't created.
__leave_with___except_simple()9 int __leave_with___except_simple() {
10   int myres = 0;
11   __try {
12     myres = 15;
13     __leave;
14     myres = 23;
15   } __except (1) {
16     return 0;
17   }
18   return 1;
19 }
20 // CHECK-LABEL: define dso_local i32 @__leave_with___except_simple()
21 // CHECK: store i32 15, i32* %myres
22 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
23 // CHECK-NOT: store i32 23
24 // CHECK: [[tryleave]]
25 // CHECK-NEXT: ret i32 1
26 
27 
28 // The "normal" case.
__leave_with___except()29 int __leave_with___except() {
30   int myres = 0;
31   __try {
32     g();
33     __leave;
34     myres = 23;
35   } __except (1) {
36     return 0;
37   }
38   return 1;
39 }
40 // CHECK-LABEL: define dso_local i32 @__leave_with___except()
41 // CHECK: invoke void @g()
42 // CHECK-NEXT:       to label %[[cont:.*]] unwind label %{{.*}}
43 // For __excepts, instead of an explicit __try.__leave label, we could use
44 // use invoke.cont as __leave jump target instead.  However, not doing this
45 // keeps the CodeGen code simpler, __leave is very rare, and SimplifyCFG will
46 // simplify this anyways.
47 // CHECK: [[cont]]
48 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
49 // CHECK-NOT: store i32 23
50 // CHECK: [[tryleave]]
51 // CHECK-NEXT: br label %
52 
53 
54 //////////////////////////////////////////////////////////////////////////////
55 // __leave with __finally
56 
57 void abort(void) __attribute__((noreturn));
58 
59 // Nothing in the __try block can trap, so __finally.cont and friends aren't
60 // created.
__leave_with___finally_simple()61 int __leave_with___finally_simple() {
62   int myres = 0;
63   __try {
64     myres = 15;
65     __leave;
66     myres = 23;
67   } __finally {
68     return 0;
69   }
70   return 1;
71 }
72 // CHECK-LABEL: define dso_local i32 @__leave_with___finally_simple()
73 // CHECK: store i32 15, i32* %myres
74 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
75 // CHECK-NOT: store i32 23
76 // CHECK: [[tryleave]]
77 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
78 // CHECK-NEXT: call void @"?fin$0@0@__leave_with___finally_simple@@"(i8 0, i8* %[[fp]])
79 
80 // __finally block doesn't return, __finally.cont doesn't exist.
__leave_with___finally_noreturn()81 int __leave_with___finally_noreturn() {
82   int myres = 0;
83   __try {
84     myres = 15;
85     __leave;
86     myres = 23;
87   } __finally {
88     abort();
89   }
90   return 1;
91 }
92 // CHECK-LABEL: define dso_local i32 @__leave_with___finally_noreturn()
93 // CHECK: store i32 15, i32* %myres
94 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
95 // CHECK-NOT: store i32 23
96 // CHECK: [[tryleave]]
97 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
98 // CHECK-NEXT: call void @"?fin$0@0@__leave_with___finally_noreturn@@"(i8 0, i8* %[[fp]])
99 
100 // The "normal" case.
__leave_with___finally()101 int __leave_with___finally() {
102   int myres = 0;
103   __try {
104     g();
105     __leave;
106     myres = 23;
107   } __finally {
108     return 0;
109   }
110   return 1;
111 }
112 // CHECK-LABEL: define dso_local i32 @__leave_with___finally()
113 // CHECK: invoke void @g()
114 // CHECK-NEXT:       to label %[[cont:.*]] unwind label %{{.*}}
115 // For __finally, there needs to be an explicit __try.__leave, because
116 // abnormal.termination.slot needs to be set there.
117 // CHECK: [[cont]]
118 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
119 // CHECK-NOT: store i32 23
120 // CHECK: [[tryleave]]
121 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
122 // CHECK-NEXT: call void @"?fin$0@0@__leave_with___finally@@"(i8 0, i8* %[[fp]])
123 
124 
125 //////////////////////////////////////////////////////////////////////////////
126 // Mixed, nested cases.
127 
nested___except___finally()128 int nested___except___finally() {
129   int myres = 0;
130   __try {
131     __try {
132       g();
133     } __finally {
134       g();
135       __leave;  // Refers to the outer __try, not the __finally!
136       myres = 23;
137       return 0;
138     }
139 
140     myres = 51;
141   } __except (1) {
142   }
143   return 1;
144 }
145 // CHECK-LABEL: define dso_local i32 @nested___except___finally()
146 
147 // CHECK-LABEL: invoke void @g()
148 // CHECK-NEXT:       to label %[[g1_cont1:.*]] unwind label %[[g1_lpad:.*]]
149 
150 // CHECK: [[g1_cont1]]
151 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
152 // CHECK-NEXT: invoke void @"?fin$0@0@nested___except___finally@@"(i8 0, i8* %[[fp]])
153 // CHECK-NEXT:       to label %[[fin_cont:.*]] unwind label %[[g2_lpad:.*]]
154 
155 // CHECK: [[fin_cont]]
156 // CHECK: store i32 51, i32* %
157 // CHECK-NEXT: br label %[[trycont:[^ ]*]]
158 
159 // CHECK: [[g1_lpad]]
160 // CHECK-NEXT: cleanuppad
161 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
162 // CHECK-NEXT: invoke void @"?fin$0@0@nested___except___finally@@"(i8 1, i8* %[[fp]])
163 // CHECK-NEXT:       to label %[[g1_resume:.*]] unwind label %[[g2_lpad]]
164 // CHECK: cleanupret {{.*}} unwind label %[[g2_lpad]]
165 
166 // CHECK: [[g2_lpad]]
167 // CHECK: catchpad {{.*}} [i8* null]
168 // CHECK: catchret
169 // CHECK: br label %[[trycont]]
170 
171 // CHECK: [[trycont]]
172 // CHECK-NEXT: ret i32 1
173 
174 // CHECK-LABEL: define internal void @"?fin$0@0@nested___except___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
175 // CHECK: call void @g()
176 // CHECK: unreachable
177 
nested___except___except()178 int nested___except___except() {
179   int myres = 0;
180   __try {
181     __try {
182       g();
183       myres = 16;
184     } __except (1) {
185       g();
186       __leave;  // Refers to the outer __try, not the __except we're in!
187       myres = 23;
188       return 0;
189     }
190 
191     myres = 51;
192   } __except (1) {
193   }
194   return 1;
195 }
196 // The order of basic blocks in the below doesn't matter.
197 // CHECK-LABEL: define dso_local i32 @nested___except___except()
198 
199 // CHECK-LABEL: invoke void @g()
200 // CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
201 
202 // CHECK: [[g1_lpad]]
203 // CHECK: catchpad {{.*}} [i8* null]
204 // CHECK: catchret {{.*}} to label %[[except:[^ ]*]]
205 // CHECK: [[except]]
206 // CHECK: invoke void @g()
207 // CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]
208 
209 // CHECK: [[g2_lpad]]
210 // CHECK: catchpad {{.*}} [i8* null]
211 // CHECK: catchret
212 // CHECK: br label %[[trycont4:[^ ]*]]
213 
214 // CHECK: [[trycont4]]
215 // CHECK-NEXT: ret i32 1
216 
217 // CHECK: [[g2_cont]]
218 // CHECK-NEXT: br label %[[tryleave:[^ ]*]]
219 // CHECK-NOT: store i32 23
220 
221 // CHECK: [[g1_cont]]
222 // CHECK: store i32 16, i32* %myres
223 // CHECK-NEXT: br label %[[trycont:[^ ]*]]
224 
225 // CHECK: [[trycont]]
226 // CHECK-NEXT: store i32 51, i32* %myres
227 // CHECK-NEXT: br label %[[tryleave]]
228 
229 // CHECK: [[tryleave]]
230 // CHECK-NEXT: br label %[[trycont4]]
231 
nested___finally___except()232 int nested___finally___except() {
233   int myres = 0;
234   __try {
235     __try {
236       g();
237     } __except (1) {
238       g();
239       __leave;  // Refers to the outer __try, not the __except!
240       myres = 23;
241       return 0;
242     }
243 
244     myres = 51;
245   } __finally {
246   }
247   return 1;
248 }
249 // The order of basic blocks in the below doesn't matter.
250 // CHECK-LABEL: define dso_local i32 @nested___finally___except()
251 
252 // CHECK-LABEL: invoke void @g()
253 // CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
254 
255 // CHECK: [[g1_lpad]]
256 // CHECK: catchpad
257 // CHECK: catchret
258 // CHECK: invoke void @g()
259 // CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]
260 
261 // CHECK: [[g2_cont]]
262 // CHECK: br label %[[tryleave:[^ ]*]]
263 // CHECK-NOT: 23
264 
265 // CHECK: [[g1_cont]]
266 // CHECK-NEXT: br label %[[trycont:[^ ]*]]
267 
268 // CHECK: [[trycont]]
269 // CHECK: store i32 51, i32* %
270 // CHECK-NEXT: br label %[[tryleave]]
271 
272 // CHECK: [[tryleave]]
273 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
274 // CHECK-NEXT: call void @"?fin$0@0@nested___finally___except@@"(i8 0, i8* %[[fp]])
275 // CHECK-NEXT: ret i32 1
276 
277 // CHECK: [[g2_lpad]]
278 // CHECK: cleanuppad
279 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
280 // CHECK-NEXT: call void @"?fin$0@0@nested___finally___except@@"(i8 1, i8* %[[fp]])
281 // CHECK: cleanupret {{.*}} unwind to caller
282 
283 // CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___except@@"(i8 %abnormal_termination, i8* %frame_pointer)
284 // CHECK: ret void
285 
nested___finally___finally()286 int nested___finally___finally() {
287   int myres = 0;
288   __try {
289     __try {
290       g();
291       myres = 16;
292     } __finally {
293       g();
294       __leave;  // Refers to the outer __try, not the __finally we're in!
295       myres = 23;
296       return 0;
297     }
298 
299     myres = 51;
300   } __finally {
301   }
302   return 1;
303 }
304 // The order of basic blocks in the below doesn't matter.
305 // CHECK-LABEL: define dso_local i32 @nested___finally___finally()
306 
307 // CHECK: invoke void @g()
308 // CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
309 
310 // CHECK: [[g1_cont]]
311 // CHECK: store i32 16, i32* %[[myres:[^ ]*]],
312 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
313 // CHECK-NEXT: invoke void @"?fin$1@0@nested___finally___finally@@"(i8 0, i8* %[[fp]])
314 // CHECK-NEXT:       to label %[[finally_cont:.*]] unwind label %[[g2_lpad:.*]]
315 
316 // CHECK: [[finally_cont]]
317 // CHECK: store i32 51, i32* %[[myres]]
318 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
319 // CHECK-NEXT: call void @"?fin$0@0@nested___finally___finally@@"(i8 0, i8* %[[fp]])
320 // CHECK-NEXT: ret i32 1
321 
322 // CHECK: [[g1_lpad]]
323 // CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad within none []
324 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
325 // CHECK-NEXT: invoke void @"?fin$1@0@nested___finally___finally@@"(i8 1, i8* %[[fp]])
326 // CHECK-NEXT:       to label %[[finally_cont2:.*]] unwind label %[[g2_lpad]]
327 // CHECK: [[finally_cont2]]
328 // CHECK: cleanupret from %[[padtoken]] unwind label %[[g2_lpad]]
329 
330 // CHECK: [[g2_lpad]]
331 // CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad within none []
332 // CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
333 // CHECK-NEXT: call void @"?fin$0@0@nested___finally___finally@@"(i8 1, i8* %[[fp]])
334 // CHECK: cleanupret from %[[padtoken]] unwind to caller
335 
336 // CHECK-LABEL: define internal void @"?fin$0@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
337 // CHECK: ret void
338 
339 // CHECK-LABEL: define internal void @"?fin$1@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
340 // CHECK: call void @g()
341 // CHECK: unreachable
342