blob: af3d987a39b55b28588f163dca7b51cd97578d71 [file] [log] [blame]
David Majnemer8a1c45d2015-12-12 05:38:55 +00001; 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
Joseph Tremoulet06125e52016-01-02 15:24:24 +00005; 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
Joseph Tremoulet131a4622016-01-02 15:25:25 +00008; RUN: sed -e s/.T8:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK8 %s
Joseph Tremoulete28885e2016-01-10 04:28:38 +00009; 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
Joseph Tremoulet81e81962016-01-10 04:30:02 +000014; 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
Joseph Tremoulet8ea80862016-01-10 04:31:05 +000018; 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
Joseph Tremoulet06125e52016-01-02 15:24:24 +000020
21declare void @g()
David Majnemer8a1c45d2015-12-12 05:38:55 +000022
23;T1: define void @f() {
24;T1: entry:
25;T1: catchret from undef to label %next
26;T1: ; CHECK1: CatchReturnInst needs to be provided a CatchPad
27;T1: next:
28;T1: unreachable
29;T1: }
30
31;T2: define void @f() {
32;T2: entry:
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
37;T2: }
38
39;T3: define void @f() {
40;T3: entry:
41;T3: cleanupret from undef unwind label %next
42;T3: ; CHECK3: CleanupReturnInst needs to be provided a CleanupPad
43;T3: next:
44;T3: unreachable
45;T3: }
46
47;T4: define void @f() {
48;T4: entry:
49;T4: %cs = catchswitch within none [label %next] unwind to caller
50;T4: next:
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
55;T4: }
Joseph Tremoulet06125e52016-01-02 15:24:24 +000056
57;T5: define void @f() personality void ()* @g {
58;T5: entry:
59;T5: ret void
60;T5: switch:
61;T5: %cs = catchswitch within none [label %catch] unwind to caller
62;T5: catch:
63;T5: catchpad within %cs []
64;T5: unreachable
65;T5: bogus:
66;T5: cleanuppad within %cs []
67;T5: ; CHECK5: CleanupPadInst has an invalid parent
68;T5: unreachable
69;T5: }
70
71;T6: define void @f() personality void ()* @g {
72;T6: entry:
73;T6: ret void
74;T6: switch1:
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
77;T6: catch1:
78;T6: catchpad within %cs1 []
79;T6: unreachable
80;T6: switch2:
81;T6: %cs2 = catchswitch within none [label %catch2] unwind to caller
82;T6: catch2:
83;T6: catchpad within %cs2 []
84;T6: unreachable
85;T6: }
86
87;T7: define void @f() personality void ()* @g {
88;T7: entry:
89;T7: ret void
90;T7: switch1:
91;T7: %cs1 = catchswitch within none [label %catch1] unwind to caller
92;T7: catch1:
93;T7: catchpad within %cs1 []
94;T7: unreachable
95;T7: switch2:
96;T7: %cs2 = catchswitch within %cs1 [label %catch2] unwind to caller
97;T7: ; CHECK7: CatchSwitchInst has an invalid parent
98;T7: catch2:
99;T7: catchpad within %cs2 []
100;T7: unreachable
101;T7: }
Joseph Tremoulet131a4622016-01-02 15:25:25 +0000102
103;T8: define void @f() personality void ()* @g {
104;T8: entry:
105;T8: ret void
106;T8: switch1:
107;T8: %cs1 = catchswitch within none [ label %switch1 ] unwind to caller
108;T8: ; CHECK8: CatchSwitchInst handlers must be catchpads
109;T8: }
Joseph Tremoulete28885e2016-01-10 04:28:38 +0000110
111;T9: define void @f() personality void ()* @g {
112;T9: entry:
113;T9: ret void
114;T9: cleanup:
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) ]
121;T9: exit:
122;T9: ret void
123;T9: }
124
125;T10: define void @f() personality void ()* @g {
126;T10: entry:
127;T10: ret void
128;T10: cleanup1:
129;T10: %cp1 = cleanuppad within none []
130;T10: unreachable
131;T10: switch:
132;T10: %cs = catchswitch within %cp1 [label %catch] unwind to caller
133;T10: catch:
134;T10: %catchp1 = catchpad within %cs [i32 1]
135;T10: unreachable
136;T10: cleanup2:
137;T10: %cp2 = cleanuppad within %catchp1 []
138;T10: unreachable
139;T10: cleanup3:
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
145;T10: }
146
147;T11: define void @f() personality void ()* @g {
148;T11: entry:
149;T11: ret void
150;T11: cleanup1:
151;T11: %cp1 = cleanuppad within none []
152;T11: unreachable
153;T11: cleanup2:
154;T11: %cp2 = cleanuppad within %cp1 []
155;T11: unreachable
156;T11: switch:
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
160;T11: catch:
161;T11: catchpad within %cs [i32 1]
162;T11: unreachable
163;T11: }
164
165;T12: define void @f() personality void ()* @g {
166;T12: entry:
167;T12: ret void
168;T12: cleanup:
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
173;T12: switch:
174;T12: %cs = catchswitch within %cp [label %catch] unwind to caller
175;T12: catch:
176;T12: catchpad within %cs [i32 1]
177;T12: unreachable
178;T12: }
179
180;T13: define void @f() personality void ()* @g {
181;T13: entry:
182;T13: ret void
183;T13: switch:
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
187;T13: catch:
188;T13: catchpad within %cs [i32 0]
189;T13: unreachable
190;T13: }
191
Joseph Tremoulet81e81962016-01-10 04:30:02 +0000192;T14: define void @f() personality void ()* @g {
193;T14: entry:
194;T14: ret void
195;T14: cleanup:
196;T14: %cp = cleanuppad within none []
197;T14: unreachable
198;T14: left:
199;T14: cleanupret from %cp unwind label %switch
200;T14: right:
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
206;T14: switch:
207;T14: %cs = catchswitch within none [label %catch] unwind to caller
208;T14: catch:
209;T14: catchpad within %cs [i32 1]
210;T14: unreachable
211;T14: }
212
213;T15: define void @f() personality void ()* @g {
214;T15: entry:
215;T15: ret void
216;T15: switch:
217;T15: %cs = catchswitch within none [label %catch] unwind to caller
218;T15: catch:
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
222;T15: unreachable:
223;T15: unreachable
224;T15: target1:
225;T15: cleanuppad within none []
226;T15: unreachable
227;T15: target2:
228;T15: cleanuppad within none []
229;T15: unreachable
230;T15: nested.1:
231;T15: %nested.pad.1 = cleanuppad within %catch.pad []
232;T15: unreachable
233;T15: nested.2:
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
241;T15: }
242
243;T16: define void @f() personality void ()* @g {
244;T16: entry:
245;T16: ret void
246;T16: switch:
247;T16: %cs = catchswitch within none [label %catch] unwind to caller
248;T16: catch:
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
257;T16: unreachable:
258;T16: unreachable
259;T16: target1:
260;T16: cleanuppad within none []
261;T16: unreachable
262;T16: }
263
264;T17: define void @f() personality void ()* @g {
265;T17: entry:
266;T17: ret void
267;T17: switch:
268;T17: %cs = catchswitch within none [label %catch] unwind label %target1
269;T17: catch:
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
278;T17: unreachable:
279;T17: unreachable
280;T17: target1:
281;T17: cleanuppad within none []
282;T17: unreachable
283;T17: target2:
284;T17: cleanuppad within none []
285;T17: unreachable
286;T17: }
Joseph Tremoulet8ea80862016-01-10 04:31:05 +0000287
288;T18: define void @f() personality void ()* @g {
289;T18: entry:
290;T18: invoke void @g()
291;T18: to label %invoke.cont unwind label %left
292;T18: invoke.cont:
293;T18: invoke void @g()
294;T18: to label %unreachable unwind label %right
295;T18: left:
296;T18: %cp.left = cleanuppad within none []
297;T18: invoke void @g() [ "funclet"(token %cp.left) ]
298;T18: to label %unreachable unwind label %right
299;T18: 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
310;T18: unreachable:
311;T18: unreachable
312;T18: }
313
314;T19: define void @f() personality void ()* @g {
315;T19: entry:
316;T19: ret void
317;T19: red:
318;T19: %redpad = cleanuppad within none []
319;T19: unreachable
320;T19: red.inner:
321;T19: %innerpad = cleanuppad within %redpad []
322;T19: invoke void @g() [ "funclet"(token %innerpad) ]
323;T19: to label %unreachable unwind label %green
324;T19: green:
325;T19: %greenswitch = catchswitch within none [label %catch] unwind label %blue
326;T19: catch:
327;T19: catchpad within %greenswitch [i32 42]
328;T19: unreachable
329;T19: blue:
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
339;T19: unreachable:
340;T19: unreachable
341;T19: }