blob: 63485d28627e77698ee0fd17a2655ef63e969680 [file] [log] [blame]
Douglas Yungcc227f82018-02-08 18:45:16 +00001; UNSUPPORTED: system-windows
Victor Leschuk7f37f072017-08-17 15:07:03 +00002
David Majnemer8cec2f22015-12-12 05:38:55 +00003; 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
Joseph Tremoulet3c6a15b2016-01-02 15:24:24 +00007; 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
Joseph Tremoulet4505d542016-01-02 15:25:25 +000010; RUN: sed -e s/.T8:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK8 %s
Joseph Tremouletfe9953a2016-01-10 04:28:38 +000011; 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
Joseph Tremouletc2d82412016-01-10 04:30:02 +000016; 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
Joseph Tremoulet12b6cd22016-01-10 04:31:05 +000020; 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
Joseph Tremoulete2fff4f2016-01-10 04:32:03 +000022; 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
David Majnemer87e42782016-02-29 22:56:36 +000024; 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
David Majnemera34c14c2016-03-01 01:19:05 +000027; RUN: sed -e s/.T25:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK25 %s
David Majnemerd724de32016-03-01 18:59:50 +000028; RUN: sed -e s/.T26:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK26 %s
Joseph Tremoulet3c6a15b2016-01-02 15:24:24 +000029
30declare void @g()
David Majnemer8cec2f22015-12-12 05:38:55 +000031
32;T1: define void @f() {
33;T1: entry:
34;T1: catchret from undef to label %next
35;T1: ; CHECK1: CatchReturnInst needs to be provided a CatchPad
36;T1: next:
37;T1: unreachable
38;T1: }
39
40;T2: define void @f() {
41;T2: entry:
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
46;T2: }
47
48;T3: define void @f() {
49;T3: entry:
50;T3: cleanupret from undef unwind label %next
51;T3: ; CHECK3: CleanupReturnInst needs to be provided a CleanupPad
52;T3: next:
53;T3: unreachable
54;T3: }
55
56;T4: define void @f() {
57;T4: entry:
58;T4: %cs = catchswitch within none [label %next] unwind to caller
59;T4: next:
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
64;T4: }
Joseph Tremoulet3c6a15b2016-01-02 15:24:24 +000065
66;T5: define void @f() personality void ()* @g {
67;T5: entry:
68;T5: ret void
69;T5: switch:
70;T5: %cs = catchswitch within none [label %catch] unwind to caller
71;T5: catch:
72;T5: catchpad within %cs []
73;T5: unreachable
74;T5: bogus:
75;T5: cleanuppad within %cs []
76;T5: ; CHECK5: CleanupPadInst has an invalid parent
77;T5: unreachable
78;T5: }
79
80;T6: define void @f() personality void ()* @g {
81;T6: entry:
82;T6: ret void
83;T6: switch1:
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
86;T6: catch1:
87;T6: catchpad within %cs1 []
88;T6: unreachable
89;T6: switch2:
90;T6: %cs2 = catchswitch within none [label %catch2] unwind to caller
91;T6: catch2:
92;T6: catchpad within %cs2 []
93;T6: unreachable
94;T6: }
95
96;T7: define void @f() personality void ()* @g {
97;T7: entry:
98;T7: ret void
99;T7: switch1:
100;T7: %cs1 = catchswitch within none [label %catch1] unwind to caller
101;T7: catch1:
102;T7: catchpad within %cs1 []
103;T7: unreachable
104;T7: switch2:
105;T7: %cs2 = catchswitch within %cs1 [label %catch2] unwind to caller
106;T7: ; CHECK7: CatchSwitchInst has an invalid parent
107;T7: catch2:
108;T7: catchpad within %cs2 []
109;T7: unreachable
110;T7: }
Joseph Tremoulet4505d542016-01-02 15:25:25 +0000111
112;T8: define void @f() personality void ()* @g {
113;T8: entry:
114;T8: ret void
115;T8: switch1:
116;T8: %cs1 = catchswitch within none [ label %switch1 ] unwind to caller
117;T8: ; CHECK8: CatchSwitchInst handlers must be catchpads
118;T8: }
Joseph Tremouletfe9953a2016-01-10 04:28:38 +0000119
120;T9: define void @f() personality void ()* @g {
121;T9: entry:
122;T9: ret void
123;T9: cleanup:
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) ]
130;T9: exit:
131;T9: ret void
132;T9: }
133
134;T10: define void @f() personality void ()* @g {
135;T10: entry:
136;T10: ret void
137;T10: cleanup1:
138;T10: %cp1 = cleanuppad within none []
139;T10: unreachable
140;T10: switch:
141;T10: %cs = catchswitch within %cp1 [label %catch] unwind to caller
142;T10: catch:
143;T10: %catchp1 = catchpad within %cs [i32 1]
144;T10: unreachable
145;T10: cleanup2:
146;T10: %cp2 = cleanuppad within %catchp1 []
147;T10: unreachable
148;T10: cleanup3:
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
154;T10: }
155
156;T11: define void @f() personality void ()* @g {
157;T11: entry:
158;T11: ret void
159;T11: cleanup1:
160;T11: %cp1 = cleanuppad within none []
161;T11: unreachable
162;T11: cleanup2:
163;T11: %cp2 = cleanuppad within %cp1 []
164;T11: unreachable
165;T11: switch:
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
169;T11: catch:
170;T11: catchpad within %cs [i32 1]
171;T11: unreachable
172;T11: }
173
174;T12: define void @f() personality void ()* @g {
175;T12: entry:
176;T12: ret void
177;T12: cleanup:
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
182;T12: switch:
183;T12: %cs = catchswitch within %cp [label %catch] unwind to caller
184;T12: catch:
185;T12: catchpad within %cs [i32 1]
186;T12: unreachable
187;T12: }
188
189;T13: define void @f() personality void ()* @g {
190;T13: entry:
191;T13: ret void
192;T13: switch:
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
196;T13: catch:
197;T13: catchpad within %cs [i32 0]
198;T13: unreachable
199;T13: }
200
Joseph Tremouletc2d82412016-01-10 04:30:02 +0000201;T14: define void @f() personality void ()* @g {
202;T14: entry:
203;T14: ret void
204;T14: cleanup:
205;T14: %cp = cleanuppad within none []
206;T14: unreachable
207;T14: left:
208;T14: cleanupret from %cp unwind label %switch
209;T14: right:
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
215;T14: switch:
216;T14: %cs = catchswitch within none [label %catch] unwind to caller
217;T14: catch:
218;T14: catchpad within %cs [i32 1]
219;T14: unreachable
220;T14: }
221
222;T15: define void @f() personality void ()* @g {
223;T15: entry:
224;T15: ret void
225;T15: switch:
226;T15: %cs = catchswitch within none [label %catch] unwind to caller
227;T15: catch:
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
231;T15: unreachable:
232;T15: unreachable
233;T15: target1:
234;T15: cleanuppad within none []
235;T15: unreachable
236;T15: target2:
237;T15: cleanuppad within none []
238;T15: unreachable
239;T15: nested.1:
240;T15: %nested.pad.1 = cleanuppad within %catch.pad []
241;T15: unreachable
242;T15: nested.2:
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
250;T15: }
251
252;T16: define void @f() personality void ()* @g {
253;T16: entry:
254;T16: ret void
255;T16: switch:
256;T16: %cs = catchswitch within none [label %catch] unwind to caller
257;T16: catch:
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
266;T16: unreachable:
267;T16: unreachable
268;T16: target1:
269;T16: cleanuppad within none []
270;T16: unreachable
271;T16: }
272
273;T17: define void @f() personality void ()* @g {
274;T17: entry:
275;T17: ret void
276;T17: switch:
277;T17: %cs = catchswitch within none [label %catch] unwind label %target1
278;T17: catch:
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
287;T17: unreachable:
288;T17: unreachable
289;T17: target1:
290;T17: cleanuppad within none []
291;T17: unreachable
292;T17: target2:
293;T17: cleanuppad within none []
294;T17: unreachable
295;T17: }
Joseph Tremoulet12b6cd22016-01-10 04:31:05 +0000296
297;T18: define void @f() personality void ()* @g {
298;T18: entry:
299;T18: invoke void @g()
300;T18: to label %invoke.cont unwind label %left
301;T18: invoke.cont:
302;T18: invoke void @g()
303;T18: to label %unreachable unwind label %right
304;T18: left:
305;T18: %cp.left = cleanuppad within none []
306;T18: invoke void @g() [ "funclet"(token %cp.left) ]
307;T18: to label %unreachable unwind label %right
308;T18: 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
319;T18: unreachable:
320;T18: unreachable
321;T18: }
322
323;T19: define void @f() personality void ()* @g {
324;T19: entry:
325;T19: ret void
326;T19: red:
327;T19: %redpad = cleanuppad within none []
328;T19: unreachable
329;T19: red.inner:
330;T19: %innerpad = cleanuppad within %redpad []
331;T19: invoke void @g() [ "funclet"(token %innerpad) ]
332;T19: to label %unreachable unwind label %green
333;T19: green:
334;T19: %greenswitch = catchswitch within none [label %catch] unwind label %blue
335;T19: catch:
336;T19: catchpad within %greenswitch [i32 42]
337;T19: unreachable
338;T19: blue:
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
348;T19: unreachable:
349;T19: unreachable
350;T19: }
Joseph Tremoulete2fff4f2016-01-10 04:32:03 +0000351
352;T20: define void @f() personality void ()* @g {
353;T20: entry:
354;T20: ret void
355;T20: switch:
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]
360;T20: catch:
361;T20: %cp = catchpad within %cs [i32 4]
362;T20: unreachable
363;T20: }
364
365;T21: define void @f() personality void ()* @g {
366;T21: entry:
367;T21: ret void
368;T21: switch:
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]
373;T21: catch1:
374;T21: %cp1 = catchpad within %cs [i32 1]
375;T21: unreachable
376;T21: catch2:
377;T21: %cp2 = catchpad within %cs [i32 2]
378;T21: unreachable
379;T21: }
David Majnemer87e42782016-02-29 22:56:36 +0000380
381;T22: define void @f() personality void ()* @g {
382;T22: invoke void @g()
383;T22: to label %merge unwind label %cleanup
384;T22:
385;T22: 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
392;T22:
393;T22: merge:
394;T22: unreachable
395;T22: }
396
397;T23: define void @f() personality void ()* @g {
398;T23: invoke void @g()
399;T23: to label %exit unwind label %pad
400;T23:
401;T23: 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 []
405;T23: unreachable
406;T23:
407;T23: exit:
408;T23: unreachable
409;T23: }
410
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
417;T24:
418;T24: pad:
419;T24: %outer = cleanuppad within %outer []
420;T24: ; CHECK24: FuncletPadInst must not be nested within itself
421;T24: ; CHECK24: %outer = cleanuppad within %outer []
422;T24: unreachable
423;T24:
424;T24: exit:
425;T24: unreachable
426;T24: }
David Majnemera34c14c2016-03-01 01:19:05 +0000427
428;T25: define void @f() personality void ()* @g {
429;T25: entry:
430;T25: unreachable
431;T25:
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
436;T25:
437;T25: catch:
438;T25: %cp2 = catchpad within %cs [i8* null, i32 64, i8* null]
439;T25: unreachable
440;T25:
441;T25: ehcleanup:
442;T25: %cp3 = cleanuppad within none []
443;T25: cleanupret from %cp3 unwind to caller
444;T25: }
David Majnemerd724de32016-03-01 18:59:50 +0000445
446;T26: define void @f() personality void ()* @g {
447;T26: entry:
448;T26: ret void
449;T26:
450;T26: ehcleanup:
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
458;T26: }