blob: f94e3a6d1cbfa5bd535f3133563a109ebd88f2ce [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 Tremouleta9a05cb2016-01-10 04:32:03 +000020; RUN: sed -e s/.T20:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK20 %s
21; RUN: sed -e s/.T21:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK21 %s
David Majnemerfe2f7f32016-02-29 22:56:36 +000022; RUN: sed -e s/.T22:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK22 %s
23; RUN: sed -e s/.T23:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK23 %s
24; RUN: sed -e s/.T24:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK24 %s
Joseph Tremoulet06125e52016-01-02 15:24:24 +000025
26declare void @g()
David Majnemer8a1c45d2015-12-12 05:38:55 +000027
28;T1: define void @f() {
29;T1: entry:
30;T1: catchret from undef to label %next
31;T1: ; CHECK1: CatchReturnInst needs to be provided a CatchPad
32;T1: next:
33;T1: unreachable
34;T1: }
35
36;T2: define void @f() {
37;T2: entry:
38;T2: %x = cleanuppad within none []
39;T2: ; catchret's first operand's operator must be catchpad
40;T2: catchret from %x to label %entry
41;T2: ; CHECK2: CatchReturnInst needs to be provided a CatchPad
42;T2: }
43
44;T3: define void @f() {
45;T3: entry:
46;T3: cleanupret from undef unwind label %next
47;T3: ; CHECK3: CleanupReturnInst needs to be provided a CleanupPad
48;T3: next:
49;T3: unreachable
50;T3: }
51
52;T4: define void @f() {
53;T4: entry:
54;T4: %cs = catchswitch within none [label %next] unwind to caller
55;T4: next:
56;T4: %x = catchpad within %cs []
57;T4: ; cleanupret first operand's operator must be cleanuppad
58;T4: cleanupret from %x unwind to caller
59;T4: ; CHECK4: CleanupReturnInst needs to be provided a CleanupPad
60;T4: }
Joseph Tremoulet06125e52016-01-02 15:24:24 +000061
62;T5: define void @f() personality void ()* @g {
63;T5: entry:
64;T5: ret void
65;T5: switch:
66;T5: %cs = catchswitch within none [label %catch] unwind to caller
67;T5: catch:
68;T5: catchpad within %cs []
69;T5: unreachable
70;T5: bogus:
71;T5: cleanuppad within %cs []
72;T5: ; CHECK5: CleanupPadInst has an invalid parent
73;T5: unreachable
74;T5: }
75
76;T6: define void @f() personality void ()* @g {
77;T6: entry:
78;T6: ret void
79;T6: switch1:
80;T6: %cs1 = catchswitch within none [label %catch1] unwind label %catch2
81;T6: ; CHECK6: Block containg CatchPadInst must be jumped to only by its catchswitch
82;T6: catch1:
83;T6: catchpad within %cs1 []
84;T6: unreachable
85;T6: switch2:
86;T6: %cs2 = catchswitch within none [label %catch2] unwind to caller
87;T6: catch2:
88;T6: catchpad within %cs2 []
89;T6: unreachable
90;T6: }
91
92;T7: define void @f() personality void ()* @g {
93;T7: entry:
94;T7: ret void
95;T7: switch1:
96;T7: %cs1 = catchswitch within none [label %catch1] unwind to caller
97;T7: catch1:
98;T7: catchpad within %cs1 []
99;T7: unreachable
100;T7: switch2:
101;T7: %cs2 = catchswitch within %cs1 [label %catch2] unwind to caller
102;T7: ; CHECK7: CatchSwitchInst has an invalid parent
103;T7: catch2:
104;T7: catchpad within %cs2 []
105;T7: unreachable
106;T7: }
Joseph Tremoulet131a4622016-01-02 15:25:25 +0000107
108;T8: define void @f() personality void ()* @g {
109;T8: entry:
110;T8: ret void
111;T8: switch1:
112;T8: %cs1 = catchswitch within none [ label %switch1 ] unwind to caller
113;T8: ; CHECK8: CatchSwitchInst handlers must be catchpads
114;T8: }
Joseph Tremoulete28885e2016-01-10 04:28:38 +0000115
116;T9: define void @f() personality void ()* @g {
117;T9: entry:
118;T9: ret void
119;T9: cleanup:
120;T9: %cp = cleanuppad within none []
121;T9: invoke void @g() [ "funclet"(token %cp) ]
122;T9: to label %exit unwind label %cleanup
123;T9: ; CHECK9: EH pad cannot handle exceptions raised within it
124;T9: ; CHECK9-NEXT: %cp = cleanuppad within none []
125;T9: ; CHECK9-NEXT: invoke void @g() [ "funclet"(token %cp) ]
126;T9: exit:
127;T9: ret void
128;T9: }
129
130;T10: define void @f() personality void ()* @g {
131;T10: entry:
132;T10: ret void
133;T10: cleanup1:
134;T10: %cp1 = cleanuppad within none []
135;T10: unreachable
136;T10: switch:
137;T10: %cs = catchswitch within %cp1 [label %catch] unwind to caller
138;T10: catch:
139;T10: %catchp1 = catchpad within %cs [i32 1]
140;T10: unreachable
141;T10: cleanup2:
142;T10: %cp2 = cleanuppad within %catchp1 []
143;T10: unreachable
144;T10: cleanup3:
145;T10: %cp3 = cleanuppad within %cp2 []
146;T10: cleanupret from %cp3 unwind label %switch
147;T10: ; CHECK10: EH pad cannot handle exceptions raised within it
148;T10: ; CHECK10-NEXT: %cs = catchswitch within %cp1 [label %catch] unwind to caller
149;T10: ; CHECK10-NEXT: cleanupret from %cp3 unwind label %switch
150;T10: }
151
152;T11: define void @f() personality void ()* @g {
153;T11: entry:
154;T11: ret void
155;T11: cleanup1:
156;T11: %cp1 = cleanuppad within none []
157;T11: unreachable
158;T11: cleanup2:
159;T11: %cp2 = cleanuppad within %cp1 []
160;T11: unreachable
161;T11: switch:
162;T11: %cs = catchswitch within none [label %catch] unwind label %cleanup2
163;T11: ; CHECK11: A single unwind edge may only enter one EH pad
164;T11: ; CHECK11-NEXT: %cs = catchswitch within none [label %catch] unwind label %cleanup2
165;T11: catch:
166;T11: catchpad within %cs [i32 1]
167;T11: unreachable
168;T11: }
169
170;T12: define void @f() personality void ()* @g {
171;T12: entry:
172;T12: ret void
173;T12: cleanup:
174;T12: %cp = cleanuppad within none []
175;T12: cleanupret from %cp unwind label %switch
176;T12: ; CHECK12: A cleanupret must exit its cleanup
177;T12: ; CHECK12-NEXT: cleanupret from %cp unwind label %switch
178;T12: switch:
179;T12: %cs = catchswitch within %cp [label %catch] unwind to caller
180;T12: catch:
181;T12: catchpad within %cs [i32 1]
182;T12: unreachable
183;T12: }
184
185;T13: define void @f() personality void ()* @g {
186;T13: entry:
187;T13: ret void
188;T13: switch:
189;T13: %cs = catchswitch within none [label %catch] unwind label %switch
190;T13: ; CHECK13: EH pad cannot handle exceptions raised within it
191;T13: ; CHECK13-NEXT: %cs = catchswitch within none [label %catch] unwind label %switch
192;T13: catch:
193;T13: catchpad within %cs [i32 0]
194;T13: unreachable
195;T13: }
196
Joseph Tremoulet81e81962016-01-10 04:30:02 +0000197;T14: define void @f() personality void ()* @g {
198;T14: entry:
199;T14: ret void
200;T14: cleanup:
201;T14: %cp = cleanuppad within none []
202;T14: unreachable
203;T14: left:
204;T14: cleanupret from %cp unwind label %switch
205;T14: right:
206;T14: cleanupret from %cp unwind to caller
207;T14: ; CHECK14: Unwind edges out of a funclet pad must have the same unwind dest
208;T14: ; CHECK14-NEXT: %cp = cleanuppad within none []
209;T14: ; CHECK14-NEXT: cleanupret from %cp unwind label %switch
210;T14: ; CHECK14-NEXT: cleanupret from %cp unwind to caller
211;T14: switch:
212;T14: %cs = catchswitch within none [label %catch] unwind to caller
213;T14: catch:
214;T14: catchpad within %cs [i32 1]
215;T14: unreachable
216;T14: }
217
218;T15: define void @f() personality void ()* @g {
219;T15: entry:
220;T15: ret void
221;T15: switch:
222;T15: %cs = catchswitch within none [label %catch] unwind to caller
223;T15: catch:
224;T15: %catch.pad = catchpad within %cs [i32 1]
225;T15: invoke void @g() [ "funclet"(token %catch.pad) ]
226;T15: to label %unreachable unwind label %target1
227;T15: unreachable:
228;T15: unreachable
229;T15: target1:
230;T15: cleanuppad within none []
231;T15: unreachable
232;T15: target2:
233;T15: cleanuppad within none []
234;T15: unreachable
235;T15: nested.1:
236;T15: %nested.pad.1 = cleanuppad within %catch.pad []
237;T15: unreachable
238;T15: nested.2:
239;T15: %nested.pad.2 = cleanuppad within %nested.pad.1 []
240;T15: cleanupret from %nested.pad.2 unwind label %target2
241;T15: ; CHECK15: Unwind edges out of a funclet pad must have the same unwind dest
242;T15: ; CHECK15-NEXT: %catch.pad = catchpad within %cs [i32 1]
243;T15: ; CHECK15-NEXT: cleanupret from %nested.pad.2 unwind label %target2
244;T15: ; CHECK15-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
245;T15: ; CHECK15-NEXT: to label %unreachable unwind label %target1
246;T15: }
247
248;T16: define void @f() personality void ()* @g {
249;T16: entry:
250;T16: ret void
251;T16: switch:
252;T16: %cs = catchswitch within none [label %catch] unwind to caller
253;T16: catch:
254;T16: %catch.pad = catchpad within %cs [i32 1]
255;T16: invoke void @g() [ "funclet"(token %catch.pad) ]
256;T16: to label %unreachable unwind label %target1
257;T16: ; CHECK16: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
258;T16: ; CHECK16-NEXT: %catch.pad = catchpad within %cs [i32 1]
259;T16: ; CHECK16-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
260;T16: ; CHECK16-NEXT: to label %unreachable unwind label %target1
261;T16: ; CHECK16-NEXT: %cs = catchswitch within none [label %catch] unwind to caller
262;T16: unreachable:
263;T16: unreachable
264;T16: target1:
265;T16: cleanuppad within none []
266;T16: unreachable
267;T16: }
268
269;T17: define void @f() personality void ()* @g {
270;T17: entry:
271;T17: ret void
272;T17: switch:
273;T17: %cs = catchswitch within none [label %catch] unwind label %target1
274;T17: catch:
275;T17: %catch.pad = catchpad within %cs [i32 1]
276;T17: invoke void @g() [ "funclet"(token %catch.pad) ]
277;T17: to label %unreachable unwind label %target2
278;T17: ; CHECK17: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
279;T17: ; CHECK17-NEXT: %catch.pad = catchpad within %cs [i32 1]
280;T17: ; CHECK17-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
281;T17: ; CHECK17-NEXT: to label %unreachable unwind label %target2
282;T17: ; CHECK17-NEXT: %cs = catchswitch within none [label %catch] unwind label %target1
283;T17: unreachable:
284;T17: unreachable
285;T17: target1:
286;T17: cleanuppad within none []
287;T17: unreachable
288;T17: target2:
289;T17: cleanuppad within none []
290;T17: unreachable
291;T17: }
Joseph Tremoulet8ea80862016-01-10 04:31:05 +0000292
293;T18: define void @f() personality void ()* @g {
294;T18: entry:
295;T18: invoke void @g()
296;T18: to label %invoke.cont unwind label %left
297;T18: invoke.cont:
298;T18: invoke void @g()
299;T18: to label %unreachable unwind label %right
300;T18: left:
301;T18: %cp.left = cleanuppad within none []
302;T18: invoke void @g() [ "funclet"(token %cp.left) ]
303;T18: to label %unreachable unwind label %right
304;T18: right:
305;T18: %cp.right = cleanuppad within none []
306;T18: invoke void @g() [ "funclet"(token %cp.right) ]
307;T18: to label %unreachable unwind label %left
308;T18: ; CHECK18: EH pads can't handle each other's exceptions
309;T18: ; CHECK18-NEXT: %cp.left = cleanuppad within none []
310;T18: ; CHECK18-NEXT: invoke void @g() [ "funclet"(token %cp.left) ]
311;T18: ; CHECK18-NEXT: to label %unreachable unwind label %right
312;T18: ; CHECK18-NEXT: %cp.right = cleanuppad within none []
313;T18: ; CHECK18-NEXT: invoke void @g() [ "funclet"(token %cp.right) ]
314;T18: ; CHECK18-NEXT: to label %unreachable unwind label %left
315;T18: unreachable:
316;T18: unreachable
317;T18: }
318
319;T19: define void @f() personality void ()* @g {
320;T19: entry:
321;T19: ret void
322;T19: red:
323;T19: %redpad = cleanuppad within none []
324;T19: unreachable
325;T19: red.inner:
326;T19: %innerpad = cleanuppad within %redpad []
327;T19: invoke void @g() [ "funclet"(token %innerpad) ]
328;T19: to label %unreachable unwind label %green
329;T19: green:
330;T19: %greenswitch = catchswitch within none [label %catch] unwind label %blue
331;T19: catch:
332;T19: catchpad within %greenswitch [i32 42]
333;T19: unreachable
334;T19: blue:
335;T19: %bluepad = cleanuppad within none []
336;T19: cleanupret from %bluepad unwind label %red
337;T19: ; CHECK19: EH pads can't handle each other's exceptions
338;T19: ; CHECK19-NEXT: %redpad = cleanuppad within none []
339;T19: ; CHECK19-NEXT: invoke void @g() [ "funclet"(token %innerpad) ]
340;T19: ; CHECK19-NEXT: to label %unreachable unwind label %green
341;T19: ; CHECK19-NEXT: %greenswitch = catchswitch within none [label %catch] unwind label %blue
342;T19: ; CHECK19-NEXT: %bluepad = cleanuppad within none []
343;T19: ; CHECK19-NEXT: cleanupret from %bluepad unwind label %red
344;T19: unreachable:
345;T19: unreachable
346;T19: }
Joseph Tremouleta9a05cb2016-01-10 04:32:03 +0000347
348;T20: define void @f() personality void ()* @g {
349;T20: entry:
350;T20: ret void
351;T20: switch:
352;T20: %cs = catchswitch within none [label %catch] unwind label %catch
353;T20: ; CHECK20: Catchswitch cannot unwind to one of its catchpads
354;T20: ; CHECK20-NEXT: %cs = catchswitch within none [label %catch] unwind label %catch
355;T20: ; CHECK20-NEXT: %cp = catchpad within %cs [i32 4]
356;T20: catch:
357;T20: %cp = catchpad within %cs [i32 4]
358;T20: unreachable
359;T20: }
360
361;T21: define void @f() personality void ()* @g {
362;T21: entry:
363;T21: ret void
364;T21: switch:
365;T21: %cs = catchswitch within none [label %catch1] unwind label %catch2
366;T21: ; CHECK21: Catchswitch cannot unwind to one of its catchpads
367;T21: ; CHECK21-NEXT: %cs = catchswitch within none [label %catch1] unwind label %catch2
368;T21: ; CHECK21-NEXT: %cp2 = catchpad within %cs [i32 2]
369;T21: catch1:
370;T21: %cp1 = catchpad within %cs [i32 1]
371;T21: unreachable
372;T21: catch2:
373;T21: %cp2 = catchpad within %cs [i32 2]
374;T21: unreachable
375;T21: }
David Majnemerfe2f7f32016-02-29 22:56:36 +0000376
377;T22: define void @f() personality void ()* @g {
378;T22: invoke void @g()
379;T22: to label %merge unwind label %cleanup
380;T22:
381;T22: cleanup:
382;T22: %outer = cleanuppad within none []
383;T22: invoke void @g() [ "funclet"(token %outer) ]
384;T22: to label %merge unwind label %merge
385;T22: ; CHECK22: The unwind destination does not have an exception handling instruction!
386;T22: ; CHECK22: invoke void @g() [ "funclet"(token %outer) ]
387;T22: ; CHECK22: to label %merge unwind label %merge
388;T22:
389;T22: merge:
390;T22: unreachable
391;T22: }
392
393;T23: define void @f() personality void ()* @g {
394;T23: invoke void @g()
395;T23: to label %exit unwind label %pad
396;T23:
397;T23: pad:
398;T23: %outer = catchpad within %outer []
399;T23: ; CHECK23: CatchPadInst needs to be directly nested in a CatchSwitchInst.
400;T23: ; CHECK23: %outer = catchpad within %outer []
401;T23: unreachable
402;T23:
403;T23: exit:
404;T23: unreachable
405;T23: }
406
407;T24: define void @f() personality void ()* @g {
408;T24: invoke void @g()
409;T24: to label %exit unwind label %pad
410;T24: ; CHECK24: A single unwind edge may only enter one EH pad
411;T24: ; CHECK24: invoke void @g()
412;T24: ; CHECK24: to label %exit unwind label %pad
413;T24:
414;T24: pad:
415;T24: %outer = cleanuppad within %outer []
416;T24: ; CHECK24: FuncletPadInst must not be nested within itself
417;T24: ; CHECK24: %outer = cleanuppad within %outer []
418;T24: unreachable
419;T24:
420;T24: exit:
421;T24: unreachable
422;T24: }