blob: 793501a9fe539cb648c256aceb9cc11e2ce93096 [file] [log] [blame]
Stephen Hines0e2c34f2015-03-23 12:09:02 -07001// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
2
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -07003void g(void);
Stephen Hines0e2c34f2015-03-23 12:09:02 -07004
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()
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -070041// CHECK: invoke void @g()
Stephen Hines0e2c34f2015-03-23 12:09:02 -070042// 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]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -070077// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
78// CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally_simple@@"(i1 zeroext false, i8* %[[fp]])
Stephen Hines0e2c34f2015-03-23 12:09:02 -070079
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]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -070097// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
98// CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally_noreturn@@"(i1 zeroext false, i8* %[[fp]])
Stephen Hines0e2c34f2015-03-23 12:09:02 -070099
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()
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700113// CHECK: invoke void @g()
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700114// 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]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700121// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
122// CHECK-NEXT: call void @"\01?fin$0@0@__leave_with___finally@@"(i1 zeroext false, i8* %[[fp]])
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700123
124
125//////////////////////////////////////////////////////////////////////////////
126// Mixed, nested cases.
127
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700128int 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}
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700145// CHECK-LABEL: define i32 @nested___except___finally()
146
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700147// CHECK-LABEL: invoke void @g()
148// CHECK-NEXT: to label %[[g1_cont1:.*]] unwind label %[[g1_lpad:.*]]
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700149
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700150// CHECK: [[g1_cont1]]
151// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
152// CHECK-NEXT: invoke void @"\01?fin$0@0@nested___except___finally@@"(i1 zeroext false, i8* %[[fp]])
153// CHECK-NEXT: to label %[[fin_cont:.*]] unwind label %[[g2_lpad:.*]]
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700154
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700155// CHECK: [[fin_cont]]
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700156// CHECK: store i32 51, i32* %
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700157// CHECK-NEXT: br label %[[trycont:[^ ]*]]
158
159// CHECK: [[g1_lpad]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700160// CHECK-NEXT: landingpad
161// CHECK-NEXT: catch i8* null
162// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
163// CHECK-NEXT: invoke void @"\01?fin$0@0@nested___except___finally@@"(i1 zeroext true, i8* %[[fp]])
164// CHECK-NEXT: to label %[[g1_resume:.*]] unwind label %[[g2_lpad]]
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700165
166// CHECK: [[g2_lpad]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700167// CHECK: br label %[[trycont]]
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700168
169// CHECK: [[trycont]]
170// CHECK-NEXT: ret i32 1
171
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700172// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___except___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer)
173// CHECK: call void @g()
174// CHECK: unreachable
175
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700176int nested___except___except() {
177 int myres = 0;
178 __try {
179 __try {
180 g();
181 myres = 16;
182 } __except (1) {
183 g();
184 __leave; // Refers to the outer __try, not the __except we're in!
185 myres = 23;
186 return 0;
187 }
188
189 myres = 51;
190 } __except (1) {
191 }
192 return 1;
193}
194// The order of basic blocks in the below doesn't matter.
195// CHECK-LABEL: define i32 @nested___except___except()
196
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700197// CHECK-LABEL: invoke void @g()
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700198// CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
199
200// CHECK: [[g1_cont]]
201// CHECK: store i32 16, i32* %myres
202// CHECK-NEXT: br label %[[trycont:[^ ]*]]
203
204// CHECK: [[g1_lpad]]
205// CHECK: br label %[[except:[^ ]*]]
206
207// CHECK: [[except]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700208// CHECK-NEXT: invoke void @g()
Stephen Hines0e2c34f2015-03-23 12:09:02 -0700209// CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]
210
211// CHECK: [[g2_cont]]
212// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
213// CHECK-NOT: store i32 23
214
215// CHECK: [[g2_lpad]]
216// CHECK: br label %[[outerexcept:[^ ]*]]
217
218// CHECK: [[outerexcept]]
219// CHECK-NEXT: br label %[[trycont4:[^ ]*]]
220
221// CHECK: [[trycont4]]
222// CHECK-NEXT: ret i32 1
223
224// CHECK: [[trycont]]
225// CHECK-NEXT: store i32 51, i32* %myres
226// CHECK-NEXT: br label %[[tryleave]]
227
228// CHECK: [[tryleave]]
229// CHECK-NEXT: br label %[[trycont4]]
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700230
231int nested___finally___except() {
232 int myres = 0;
233 __try {
234 __try {
235 g();
236 } __except (1) {
237 g();
238 __leave; // Refers to the outer __try, not the __except!
239 myres = 23;
240 return 0;
241 }
242
243 myres = 51;
244 } __finally {
245 }
246 return 1;
247}
248// The order of basic blocks in the below doesn't matter.
249// CHECK-LABEL: define i32 @nested___finally___except()
250
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700251// CHECK-LABEL: invoke void @g()
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700252// CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
253
254// CHECK: [[g1_cont]]
255// CHECK-NEXT: br label %[[trycont:[^ ]*]]
256
257// CHECK: [[g1_lpad]]
258// CHECK: br label %[[except:[^ ]*]]
259
260// CHECK: [[except]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700261// CHECK-NEXT: invoke void @g()
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700262// CHECK-NEXT: to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]
263
264// CHECK: [[g2_cont]]
265// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
266// CHECK-NOT: 23
267
268// CHECK: [[g2_lpad]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700269// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
270// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___except@@"(i1 zeroext true, i8* %[[fp]])
271// CHECK-NEXT: br label %[[ehresume:[^ ]*]]
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700272
273// CHECK: [[trycont]]
274// CHECK: store i32 51, i32* %
275// CHECK-NEXT: br label %[[tryleave]]
276
277// CHECK: [[tryleave]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700278// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
279// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___except@@"(i1 zeroext false, i8* %[[fp]])
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700280// CHECK-NEXT: ret i32 1
281
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700282// CHECK: [[ehresume]]
283// CHECK: resume
284
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700285// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___except@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer)
286// CHECK: ret void
287
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700288int nested___finally___finally() {
289 int myres = 0;
290 __try {
291 __try {
292 g();
293 myres = 16;
294 } __finally {
295 g();
296 __leave; // Refers to the outer __try, not the __finally we're in!
297 myres = 23;
298 return 0;
299 }
300
301 myres = 51;
302 } __finally {
303 }
304 return 1;
305}
306// The order of basic blocks in the below doesn't matter.
307// CHECK-LABEL: define i32 @nested___finally___finally()
308
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700309// CHECK-LABEL: invoke void @g()
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700310// CHECK-NEXT: to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
311
312// CHECK: [[g1_cont]]
313// CHECK: store i32 16, i32* %[[myres:[^ ]*]],
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700314// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
315// CHECK-NEXT: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext false, i8* %[[fp]])
316// CHECK-NEXT: to label %[[finally_cont:.*]] unwind label %[[g2_lpad:.*]]
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700317
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700318// CHECK: [[finally_cont]]
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700319// CHECK: store i32 51, i32* %[[myres]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700320// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
321// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext false, i8* %[[fp]])
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700322// CHECK-NEXT: ret i32 1
323
324// CHECK: [[g1_lpad]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700325// CHECK-NEXT: landingpad
326// CHECK-NEXT: cleanup
327// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
328// CHECK-NEXT: invoke void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext true, i8* %[[fp]])
329// CHECK-NEXT: to label %[[finally_cont2:.*]] unwind label %[[g2_lpad]]
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700330
331// CHECK: [[g2_lpad]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700332// CHECK-NEXT: landingpad
333// CHECK-NEXT: cleanup
334// CHECK: br label %[[ehcleanup:.*]]
335
336// CHECK: [[finally_cont2]]
337// CHECK: br label %[[ehcleanup]]
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700338
339// CHECK: [[ehcleanup]]
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700340// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0)
341// CHECK-NEXT: call void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext true, i8* %[[fp]])
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -0700342// CHECK: resume
Pirama Arumuga Nainar33337ca2015-05-06 11:48:57 -0700343
344// CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer)
345// CHECK: ret void
346
347// CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"(i1 zeroext %abnormal_termination, i8* %frame_pointer)
348// CHECK: call void @g()
349// CHECK: unreachable