1 ; RUN: sed -e s/.T1:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK1 %s
2 ; RUN: sed -e s/.T2:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK2 %s
3 ; RUN: sed -e s/.T3:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK3 %s
4 ; RUN: sed -e s/.T4:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK4 %s
5 ; RUN: sed -e s/.T5:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK5 %s
6 ; RUN: sed -e s/.T6:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK6 %s
7 ; RUN: sed -e s/.T7:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK7 %s
8 ; RUN: sed -e s/.T8:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK8 %s
9 ; RUN: sed -e s/.T9:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK9 %s
10 ; RUN: sed -e s/.T10:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK10 %s
11 ; RUN: sed -e s/.T11:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK11 %s
12 ; RUN: sed -e s/.T12:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK12 %s
13 ; RUN: sed -e s/.T13:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK13 %s
14 ; RUN: sed -e s/.T14:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK14 %s
15 ; RUN: sed -e s/.T15:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK15 %s
16 ; RUN: sed -e s/.T16:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK16 %s
17 ; RUN: sed -e s/.T17:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK17 %s
18 ; RUN: sed -e s/.T18:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK18 %s
19 ; RUN: sed -e s/.T19:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK19 %s
23 ;T1: define void @f() {
25 ;T1: catchret from undef to label %next
26 ;T1: ; CHECK1: CatchReturnInst needs to be provided a CatchPad
31 ;T2: define void @f() {
33 ;T2: %x = cleanuppad within none []
34 ;T2: ; catchret's first operand's operator must be catchpad
35 ;T2: catchret from %x to label %entry
36 ;T2: ; CHECK2: CatchReturnInst needs to be provided a CatchPad
39 ;T3: define void @f() {
41 ;T3: cleanupret from undef unwind label %next
42 ;T3: ; CHECK3: CleanupReturnInst needs to be provided a CleanupPad
47 ;T4: define void @f() {
49 ;T4: %cs = catchswitch within none [label %next] unwind to caller
51 ;T4: %x = catchpad within %cs []
52 ;T4: ; cleanupret first operand's operator must be cleanuppad
53 ;T4: cleanupret from %x unwind to caller
54 ;T4: ; CHECK4: CleanupReturnInst needs to be provided a CleanupPad
57 ;T5: define void @f() personality void ()* @g {
61 ;T5: %cs = catchswitch within none [label %catch] unwind to caller
63 ;T5: catchpad within %cs []
66 ;T5: cleanuppad within %cs []
67 ;T5: ; CHECK5: CleanupPadInst has an invalid parent
71 ;T6: define void @f() personality void ()* @g {
75 ;T6: %cs1 = catchswitch within none [label %catch1] unwind label %catch2
76 ;T6: ; CHECK6: Block containg CatchPadInst must be jumped to only by its catchswitch
78 ;T6: catchpad within %cs1 []
81 ;T6: %cs2 = catchswitch within none [label %catch2] unwind to caller
83 ;T6: catchpad within %cs2 []
87 ;T7: define void @f() personality void ()* @g {
91 ;T7: %cs1 = catchswitch within none [label %catch1] unwind to caller
93 ;T7: catchpad within %cs1 []
96 ;T7: %cs2 = catchswitch within %cs1 [label %catch2] unwind to caller
97 ;T7: ; CHECK7: CatchSwitchInst has an invalid parent
99 ;T7: catchpad within %cs2 []
103 ;T8: define void @f() personality void ()* @g {
107 ;T8: %cs1 = catchswitch within none [ label %switch1 ] unwind to caller
108 ;T8: ; CHECK8: CatchSwitchInst handlers must be catchpads
111 ;T9: define void @f() personality void ()* @g {
115 ;T9: %cp = cleanuppad within none []
116 ;T9: invoke void @g() [ "funclet"(token %cp) ]
117 ;T9: to label %exit unwind label %cleanup
118 ;T9: ; CHECK9: EH pad cannot handle exceptions raised within it
119 ;T9: ; CHECK9-NEXT: %cp = cleanuppad within none []
120 ;T9: ; CHECK9-NEXT: invoke void @g() [ "funclet"(token %cp) ]
125 ;T10: define void @f() personality void ()* @g {
129 ;T10: %cp1 = cleanuppad within none []
132 ;T10: %cs = catchswitch within %cp1 [label %catch] unwind to caller
134 ;T10: %catchp1 = catchpad within %cs [i32 1]
137 ;T10: %cp2 = cleanuppad within %catchp1 []
140 ;T10: %cp3 = cleanuppad within %cp2 []
141 ;T10: cleanupret from %cp3 unwind label %switch
142 ;T10: ; CHECK10: EH pad cannot handle exceptions raised within it
143 ;T10: ; CHECK10-NEXT: %cs = catchswitch within %cp1 [label %catch] unwind to caller
144 ;T10: ; CHECK10-NEXT: cleanupret from %cp3 unwind label %switch
147 ;T11: define void @f() personality void ()* @g {
151 ;T11: %cp1 = cleanuppad within none []
154 ;T11: %cp2 = cleanuppad within %cp1 []
157 ;T11: %cs = catchswitch within none [label %catch] unwind label %cleanup2
158 ;T11: ; CHECK11: A single unwind edge may only enter one EH pad
159 ;T11: ; CHECK11-NEXT: %cs = catchswitch within none [label %catch] unwind label %cleanup2
161 ;T11: catchpad within %cs [i32 1]
165 ;T12: define void @f() personality void ()* @g {
169 ;T12: %cp = cleanuppad within none []
170 ;T12: cleanupret from %cp unwind label %switch
171 ;T12: ; CHECK12: A cleanupret must exit its cleanup
172 ;T12: ; CHECK12-NEXT: cleanupret from %cp unwind label %switch
174 ;T12: %cs = catchswitch within %cp [label %catch] unwind to caller
176 ;T12: catchpad within %cs [i32 1]
180 ;T13: define void @f() personality void ()* @g {
184 ;T13: %cs = catchswitch within none [label %catch] unwind label %switch
185 ;T13: ; CHECK13: EH pad cannot handle exceptions raised within it
186 ;T13: ; CHECK13-NEXT: %cs = catchswitch within none [label %catch] unwind label %switch
188 ;T13: catchpad within %cs [i32 0]
192 ;T14: define void @f() personality void ()* @g {
196 ;T14: %cp = cleanuppad within none []
199 ;T14: cleanupret from %cp unwind label %switch
201 ;T14: cleanupret from %cp unwind to caller
202 ;T14: ; CHECK14: Unwind edges out of a funclet pad must have the same unwind dest
203 ;T14: ; CHECK14-NEXT: %cp = cleanuppad within none []
204 ;T14: ; CHECK14-NEXT: cleanupret from %cp unwind label %switch
205 ;T14: ; CHECK14-NEXT: cleanupret from %cp unwind to caller
207 ;T14: %cs = catchswitch within none [label %catch] unwind to caller
209 ;T14: catchpad within %cs [i32 1]
213 ;T15: define void @f() personality void ()* @g {
217 ;T15: %cs = catchswitch within none [label %catch] unwind to caller
219 ;T15: %catch.pad = catchpad within %cs [i32 1]
220 ;T15: invoke void @g() [ "funclet"(token %catch.pad) ]
221 ;T15: to label %unreachable unwind label %target1
225 ;T15: cleanuppad within none []
228 ;T15: cleanuppad within none []
231 ;T15: %nested.pad.1 = cleanuppad within %catch.pad []
234 ;T15: %nested.pad.2 = cleanuppad within %nested.pad.1 []
235 ;T15: cleanupret from %nested.pad.2 unwind label %target2
236 ;T15: ; CHECK15: Unwind edges out of a funclet pad must have the same unwind dest
237 ;T15: ; CHECK15-NEXT: %catch.pad = catchpad within %cs [i32 1]
238 ;T15: ; CHECK15-NEXT: cleanupret from %nested.pad.2 unwind label %target2
239 ;T15: ; CHECK15-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
240 ;T15: ; CHECK15-NEXT: to label %unreachable unwind label %target1
243 ;T16: define void @f() personality void ()* @g {
247 ;T16: %cs = catchswitch within none [label %catch] unwind to caller
249 ;T16: %catch.pad = catchpad within %cs [i32 1]
250 ;T16: invoke void @g() [ "funclet"(token %catch.pad) ]
251 ;T16: to label %unreachable unwind label %target1
252 ;T16: ; CHECK16: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
253 ;T16: ; CHECK16-NEXT: %catch.pad = catchpad within %cs [i32 1]
254 ;T16: ; CHECK16-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
255 ;T16: ; CHECK16-NEXT: to label %unreachable unwind label %target1
256 ;T16: ; CHECK16-NEXT: %cs = catchswitch within none [label %catch] unwind to caller
260 ;T16: cleanuppad within none []
264 ;T17: define void @f() personality void ()* @g {
268 ;T17: %cs = catchswitch within none [label %catch] unwind label %target1
270 ;T17: %catch.pad = catchpad within %cs [i32 1]
271 ;T17: invoke void @g() [ "funclet"(token %catch.pad) ]
272 ;T17: to label %unreachable unwind label %target2
273 ;T17: ; CHECK17: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
274 ;T17: ; CHECK17-NEXT: %catch.pad = catchpad within %cs [i32 1]
275 ;T17: ; CHECK17-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
276 ;T17: ; CHECK17-NEXT: to label %unreachable unwind label %target2
277 ;T17: ; CHECK17-NEXT: %cs = catchswitch within none [label %catch] unwind label %target1
281 ;T17: cleanuppad within none []
284 ;T17: cleanuppad within none []
288 ;T18: define void @f() personality void ()* @g {
290 ;T18: invoke void @g()
291 ;T18: to label %invoke.cont unwind label %left
293 ;T18: invoke void @g()
294 ;T18: to label %unreachable unwind label %right
296 ;T18: %cp.left = cleanuppad within none []
297 ;T18: invoke void @g() [ "funclet"(token %cp.left) ]
298 ;T18: to label %unreachable unwind label %right
300 ;T18: %cp.right = cleanuppad within none []
301 ;T18: invoke void @g() [ "funclet"(token %cp.right) ]
302 ;T18: to label %unreachable unwind label %left
303 ;T18: ; CHECK18: EH pads can't handle each other's exceptions
304 ;T18: ; CHECK18-NEXT: %cp.left = cleanuppad within none []
305 ;T18: ; CHECK18-NEXT: invoke void @g() [ "funclet"(token %cp.left) ]
306 ;T18: ; CHECK18-NEXT: to label %unreachable unwind label %right
307 ;T18: ; CHECK18-NEXT: %cp.right = cleanuppad within none []
308 ;T18: ; CHECK18-NEXT: invoke void @g() [ "funclet"(token %cp.right) ]
309 ;T18: ; CHECK18-NEXT: to label %unreachable unwind label %left
314 ;T19: define void @f() personality void ()* @g {
318 ;T19: %redpad = cleanuppad within none []
321 ;T19: %innerpad = cleanuppad within %redpad []
322 ;T19: invoke void @g() [ "funclet"(token %innerpad) ]
323 ;T19: to label %unreachable unwind label %green
325 ;T19: %greenswitch = catchswitch within none [label %catch] unwind label %blue
327 ;T19: catchpad within %greenswitch [i32 42]
330 ;T19: %bluepad = cleanuppad within none []
331 ;T19: cleanupret from %bluepad unwind label %red
332 ;T19: ; CHECK19: EH pads can't handle each other's exceptions
333 ;T19: ; CHECK19-NEXT: %redpad = cleanuppad within none []
334 ;T19: ; CHECK19-NEXT: invoke void @g() [ "funclet"(token %innerpad) ]
335 ;T19: ; CHECK19-NEXT: to label %unreachable unwind label %green
336 ;T19: ; CHECK19-NEXT: %greenswitch = catchswitch within none [label %catch] unwind label %blue
337 ;T19: ; CHECK19-NEXT: %bluepad = cleanuppad within none []
338 ;T19: ; CHECK19-NEXT: cleanupret from %bluepad unwind label %red