1 ; UNSUPPORTED: system-windows
3 ; RUN: sed -e s/.T1:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK1 %s
4 ; RUN: sed -e s/.T2:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK2 %s
5 ; RUN: sed -e s/.T3:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK3 %s
6 ; RUN: sed -e s/.T4:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK4 %s
7 ; RUN: sed -e s/.T5:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK5 %s
8 ; RUN: sed -e s/.T6:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK6 %s
9 ; RUN: sed -e s/.T7:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK7 %s
10 ; RUN: sed -e s/.T8:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK8 %s
11 ; RUN: sed -e s/.T9:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK9 %s
12 ; RUN: sed -e s/.T10:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK10 %s
13 ; RUN: sed -e s/.T11:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK11 %s
14 ; RUN: sed -e s/.T12:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK12 %s
15 ; RUN: sed -e s/.T13:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK13 %s
16 ; RUN: sed -e s/.T14:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK14 %s
17 ; RUN: sed -e s/.T15:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK15 %s
18 ; RUN: sed -e s/.T16:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK16 %s
19 ; RUN: sed -e s/.T17:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK17 %s
20 ; RUN: sed -e s/.T18:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK18 %s
21 ; RUN: sed -e s/.T19:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK19 %s
22 ; RUN: sed -e s/.T20:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK20 %s
23 ; RUN: sed -e s/.T21:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK21 %s
24 ; RUN: sed -e s/.T22:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK22 %s
25 ; RUN: sed -e s/.T23:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK23 %s
26 ; RUN: sed -e s/.T24:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK24 %s
27 ; RUN: sed -e s/.T25:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK25 %s
28 ; RUN: sed -e s/.T26:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK26 %s
32 ;T1: define void @f() {
34 ;T1: catchret from undef to label %next
35 ;T1: ; CHECK1: CatchReturnInst needs to be provided a CatchPad
40 ;T2: define void @f() {
42 ;T2: %x = cleanuppad within none []
43 ;T2: ; catchret's first operand's operator must be catchpad
44 ;T2: catchret from %x to label %entry
45 ;T2: ; CHECK2: CatchReturnInst needs to be provided a CatchPad
48 ;T3: define void @f() {
50 ;T3: cleanupret from undef unwind label %next
51 ;T3: ; CHECK3: CleanupReturnInst needs to be provided a CleanupPad
56 ;T4: define void @f() {
58 ;T4: %cs = catchswitch within none [label %next] unwind to caller
60 ;T4: %x = catchpad within %cs []
61 ;T4: ; cleanupret first operand's operator must be cleanuppad
62 ;T4: cleanupret from %x unwind to caller
63 ;T4: ; CHECK4: CleanupReturnInst needs to be provided a CleanupPad
66 ;T5: define void @f() personality void ()* @g {
70 ;T5: %cs = catchswitch within none [label %catch] unwind to caller
72 ;T5: catchpad within %cs []
75 ;T5: cleanuppad within %cs []
76 ;T5: ; CHECK5: CleanupPadInst has an invalid parent
80 ;T6: define void @f() personality void ()* @g {
84 ;T6: %cs1 = catchswitch within none [label %catch1] unwind label %catch2
85 ;T6: ; CHECK6: Block containg CatchPadInst must be jumped to only by its catchswitch
87 ;T6: catchpad within %cs1 []
90 ;T6: %cs2 = catchswitch within none [label %catch2] unwind to caller
92 ;T6: catchpad within %cs2 []
96 ;T7: define void @f() personality void ()* @g {
100 ;T7: %cs1 = catchswitch within none [label %catch1] unwind to caller
102 ;T7: catchpad within %cs1 []
105 ;T7: %cs2 = catchswitch within %cs1 [label %catch2] unwind to caller
106 ;T7: ; CHECK7: CatchSwitchInst has an invalid parent
108 ;T7: catchpad within %cs2 []
112 ;T8: define void @f() personality void ()* @g {
116 ;T8: %cs1 = catchswitch within none [ label %switch1 ] unwind to caller
117 ;T8: ; CHECK8: CatchSwitchInst handlers must be catchpads
120 ;T9: define void @f() personality void ()* @g {
124 ;T9: %cp = cleanuppad within none []
125 ;T9: invoke void @g() [ "funclet"(token %cp) ]
126 ;T9: to label %exit unwind label %cleanup
127 ;T9: ; CHECK9: EH pad cannot handle exceptions raised within it
128 ;T9: ; CHECK9-NEXT: %cp = cleanuppad within none []
129 ;T9: ; CHECK9-NEXT: invoke void @g() [ "funclet"(token %cp) ]
134 ;T10: define void @f() personality void ()* @g {
138 ;T10: %cp1 = cleanuppad within none []
141 ;T10: %cs = catchswitch within %cp1 [label %catch] unwind to caller
143 ;T10: %catchp1 = catchpad within %cs [i32 1]
146 ;T10: %cp2 = cleanuppad within %catchp1 []
149 ;T10: %cp3 = cleanuppad within %cp2 []
150 ;T10: cleanupret from %cp3 unwind label %switch
151 ;T10: ; CHECK10: EH pad cannot handle exceptions raised within it
152 ;T10: ; CHECK10-NEXT: %cs = catchswitch within %cp1 [label %catch] unwind to caller
153 ;T10: ; CHECK10-NEXT: cleanupret from %cp3 unwind label %switch
156 ;T11: define void @f() personality void ()* @g {
160 ;T11: %cp1 = cleanuppad within none []
163 ;T11: %cp2 = cleanuppad within %cp1 []
166 ;T11: %cs = catchswitch within none [label %catch] unwind label %cleanup2
167 ;T11: ; CHECK11: A single unwind edge may only enter one EH pad
168 ;T11: ; CHECK11-NEXT: %cs = catchswitch within none [label %catch] unwind label %cleanup2
170 ;T11: catchpad within %cs [i32 1]
174 ;T12: define void @f() personality void ()* @g {
178 ;T12: %cp = cleanuppad within none []
179 ;T12: cleanupret from %cp unwind label %switch
180 ;T12: ; CHECK12: A cleanupret must exit its cleanup
181 ;T12: ; CHECK12-NEXT: cleanupret from %cp unwind label %switch
183 ;T12: %cs = catchswitch within %cp [label %catch] unwind to caller
185 ;T12: catchpad within %cs [i32 1]
189 ;T13: define void @f() personality void ()* @g {
193 ;T13: %cs = catchswitch within none [label %catch] unwind label %switch
194 ;T13: ; CHECK13: EH pad cannot handle exceptions raised within it
195 ;T13: ; CHECK13-NEXT: %cs = catchswitch within none [label %catch] unwind label %switch
197 ;T13: catchpad within %cs [i32 0]
201 ;T14: define void @f() personality void ()* @g {
205 ;T14: %cp = cleanuppad within none []
208 ;T14: cleanupret from %cp unwind label %switch
210 ;T14: cleanupret from %cp unwind to caller
211 ;T14: ; CHECK14: Unwind edges out of a funclet pad must have the same unwind dest
212 ;T14: ; CHECK14-NEXT: %cp = cleanuppad within none []
213 ;T14: ; CHECK14-NEXT: cleanupret from %cp unwind label %switch
214 ;T14: ; CHECK14-NEXT: cleanupret from %cp unwind to caller
216 ;T14: %cs = catchswitch within none [label %catch] unwind to caller
218 ;T14: catchpad within %cs [i32 1]
222 ;T15: define void @f() personality void ()* @g {
226 ;T15: %cs = catchswitch within none [label %catch] unwind to caller
228 ;T15: %catch.pad = catchpad within %cs [i32 1]
229 ;T15: invoke void @g() [ "funclet"(token %catch.pad) ]
230 ;T15: to label %unreachable unwind label %target1
234 ;T15: cleanuppad within none []
237 ;T15: cleanuppad within none []
240 ;T15: %nested.pad.1 = cleanuppad within %catch.pad []
243 ;T15: %nested.pad.2 = cleanuppad within %nested.pad.1 []
244 ;T15: cleanupret from %nested.pad.2 unwind label %target2
245 ;T15: ; CHECK15: Unwind edges out of a funclet pad must have the same unwind dest
246 ;T15: ; CHECK15-NEXT: %catch.pad = catchpad within %cs [i32 1]
247 ;T15: ; CHECK15-NEXT: cleanupret from %nested.pad.2 unwind label %target2
248 ;T15: ; CHECK15-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
249 ;T15: ; CHECK15-NEXT: to label %unreachable unwind label %target1
252 ;T16: define void @f() personality void ()* @g {
256 ;T16: %cs = catchswitch within none [label %catch] unwind to caller
258 ;T16: %catch.pad = catchpad within %cs [i32 1]
259 ;T16: invoke void @g() [ "funclet"(token %catch.pad) ]
260 ;T16: to label %unreachable unwind label %target1
261 ;T16: ; CHECK16: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
262 ;T16: ; CHECK16-NEXT: %catch.pad = catchpad within %cs [i32 1]
263 ;T16: ; CHECK16-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
264 ;T16: ; CHECK16-NEXT: to label %unreachable unwind label %target1
265 ;T16: ; CHECK16-NEXT: %cs = catchswitch within none [label %catch] unwind to caller
269 ;T16: cleanuppad within none []
273 ;T17: define void @f() personality void ()* @g {
277 ;T17: %cs = catchswitch within none [label %catch] unwind label %target1
279 ;T17: %catch.pad = catchpad within %cs [i32 1]
280 ;T17: invoke void @g() [ "funclet"(token %catch.pad) ]
281 ;T17: to label %unreachable unwind label %target2
282 ;T17: ; CHECK17: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
283 ;T17: ; CHECK17-NEXT: %catch.pad = catchpad within %cs [i32 1]
284 ;T17: ; CHECK17-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
285 ;T17: ; CHECK17-NEXT: to label %unreachable unwind label %target2
286 ;T17: ; CHECK17-NEXT: %cs = catchswitch within none [label %catch] unwind label %target1
290 ;T17: cleanuppad within none []
293 ;T17: cleanuppad within none []
297 ;T18: define void @f() personality void ()* @g {
299 ;T18: invoke void @g()
300 ;T18: to label %invoke.cont unwind label %left
302 ;T18: invoke void @g()
303 ;T18: to label %unreachable unwind label %right
305 ;T18: %cp.left = cleanuppad within none []
306 ;T18: invoke void @g() [ "funclet"(token %cp.left) ]
307 ;T18: to label %unreachable unwind label %right
309 ;T18: %cp.right = cleanuppad within none []
310 ;T18: invoke void @g() [ "funclet"(token %cp.right) ]
311 ;T18: to label %unreachable unwind label %left
312 ;T18: ; CHECK18: EH pads can't handle each other's exceptions
313 ;T18: ; CHECK18-NEXT: %cp.left = cleanuppad within none []
314 ;T18: ; CHECK18-NEXT: invoke void @g() [ "funclet"(token %cp.left) ]
315 ;T18: ; CHECK18-NEXT: to label %unreachable unwind label %right
316 ;T18: ; CHECK18-NEXT: %cp.right = cleanuppad within none []
317 ;T18: ; CHECK18-NEXT: invoke void @g() [ "funclet"(token %cp.right) ]
318 ;T18: ; CHECK18-NEXT: to label %unreachable unwind label %left
323 ;T19: define void @f() personality void ()* @g {
327 ;T19: %redpad = cleanuppad within none []
330 ;T19: %innerpad = cleanuppad within %redpad []
331 ;T19: invoke void @g() [ "funclet"(token %innerpad) ]
332 ;T19: to label %unreachable unwind label %green
334 ;T19: %greenswitch = catchswitch within none [label %catch] unwind label %blue
336 ;T19: catchpad within %greenswitch [i32 42]
339 ;T19: %bluepad = cleanuppad within none []
340 ;T19: cleanupret from %bluepad unwind label %red
341 ;T19: ; CHECK19: EH pads can't handle each other's exceptions
342 ;T19: ; CHECK19-NEXT: %redpad = cleanuppad within none []
343 ;T19: ; CHECK19-NEXT: invoke void @g() [ "funclet"(token %innerpad) ]
344 ;T19: ; CHECK19-NEXT: to label %unreachable unwind label %green
345 ;T19: ; CHECK19-NEXT: %greenswitch = catchswitch within none [label %catch] unwind label %blue
346 ;T19: ; CHECK19-NEXT: %bluepad = cleanuppad within none []
347 ;T19: ; CHECK19-NEXT: cleanupret from %bluepad unwind label %red
352 ;T20: define void @f() personality void ()* @g {
356 ;T20: %cs = catchswitch within none [label %catch] unwind label %catch
357 ;T20: ; CHECK20: Catchswitch cannot unwind to one of its catchpads
358 ;T20: ; CHECK20-NEXT: %cs = catchswitch within none [label %catch] unwind label %catch
359 ;T20: ; CHECK20-NEXT: %cp = catchpad within %cs [i32 4]
361 ;T20: %cp = catchpad within %cs [i32 4]
365 ;T21: define void @f() personality void ()* @g {
369 ;T21: %cs = catchswitch within none [label %catch1] unwind label %catch2
370 ;T21: ; CHECK21: Catchswitch cannot unwind to one of its catchpads
371 ;T21: ; CHECK21-NEXT: %cs = catchswitch within none [label %catch1] unwind label %catch2
372 ;T21: ; CHECK21-NEXT: %cp2 = catchpad within %cs [i32 2]
374 ;T21: %cp1 = catchpad within %cs [i32 1]
377 ;T21: %cp2 = catchpad within %cs [i32 2]
381 ;T22: define void @f() personality void ()* @g {
382 ;T22: invoke void @g()
383 ;T22: to label %merge unwind label %cleanup
386 ;T22: %outer = cleanuppad within none []
387 ;T22: invoke void @g() [ "funclet"(token %outer) ]
388 ;T22: to label %merge unwind label %merge
389 ;T22: ; CHECK22: The unwind destination does not have an exception handling instruction!
390 ;T22: ; CHECK22: invoke void @g() [ "funclet"(token %outer) ]
391 ;T22: ; CHECK22: to label %merge unwind label %merge
397 ;T23: define void @f() personality void ()* @g {
398 ;T23: invoke void @g()
399 ;T23: to label %exit unwind label %pad
402 ;T23: %outer = catchpad within %outer []
403 ;T23: ; CHECK23: CatchPadInst needs to be directly nested in a CatchSwitchInst.
404 ;T23: ; CHECK23: %outer = catchpad within %outer []
411 ;T24: define void @f() personality void ()* @g {
412 ;T24: invoke void @g()
413 ;T24: to label %exit unwind label %pad
414 ;T24: ; CHECK24: A single unwind edge may only enter one EH pad
415 ;T24: ; CHECK24: invoke void @g()
416 ;T24: ; CHECK24: to label %exit unwind label %pad
419 ;T24: %outer = cleanuppad within %outer []
420 ;T24: ; CHECK24: FuncletPadInst must not be nested within itself
421 ;T24: ; CHECK24: %outer = cleanuppad within %outer []
428 ;T25: define void @f() personality void ()* @g {
432 ;T25: catch.dispatch:
433 ;T25: %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup
434 ;T25: ; CHECK25: EH pad jumps through a cycle of pads
435 ;T25: ; CHECK25: %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup
438 ;T25: %cp2 = catchpad within %cs [i8* null, i32 64, i8* null]
442 ;T25: %cp3 = cleanuppad within none []
443 ;T25: cleanupret from %cp3 unwind to caller
446 ;T26: define void @f() personality void ()* @g {
451 ;T26: cleanuppad within none []
452 ;T26: cleanupret from none unwind label %ehcleanup
453 ;T26: ; CHECK26: A cleanupret must exit its cleanup
454 ;T26: ; CHECK26: cleanupret from none unwind label %ehcleanup
455 ;T26: ; CHECK26: CleanupReturnInst needs to be provided a CleanupPad
456 ;T26: ; CHECK26: cleanupret from none unwind label %ehcleanup
457 ;T26: ; CHECK26: token none