1// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | opt -instnamer -S | FileCheck %s
2
3void g(void);
4
5//////////////////////////////////////////////////////////////////////////////
6// __leave with __except
7
8// Nothing in the __try block can trap, so __try.cont isn't created.
9int __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 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.
29int __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 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
57void abort(void) __attribute__((noreturn));
58
59// Nothing in the __try block can trap, so __finally.cont and friends aren't
60// created.
61int __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 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 @"\01?fin$0@0@__leave_with___finally_simple@@"(i8 0, i8* %[[fp]])
79
80// __finally block doesn't return, __finally.cont doesn't exist.
81int __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 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 @"\01?fin$0@0@__leave_with___finally_noreturn@@"(i8 0, i8* %[[fp]])
99
100// The "normal" case.
101int __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 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 @"\01?fin$0@0@__leave_with___finally@@"(i8 0, i8* %[[fp]])
123
124
125//////////////////////////////////////////////////////////////////////////////
126// Mixed, nested cases.
127
128int 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 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 @"\01?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 @"\01?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 @"\01?fin$0@0@nested___except___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
175// CHECK: call void @g()
176// CHECK: unreachable
177
178int 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 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
232int 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 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 @"\01?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 @"\01?fin$0@0@nested___finally___except@@"(i8 1, i8* %[[fp]])
281// CHECK: cleanupret {{.*}} unwind to caller
282
283// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___except@@"(i8 %abnormal_termination, i8* %frame_pointer)
284// CHECK: ret void
285
286int 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 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 @"\01?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 @"\01?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 @"\01?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 @"\01?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 @"\01?fin$0@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
337// CHECK: ret void
338
339// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
340// CHECK: call void @g()
341// CHECK: unreachable
342