• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; UNSUPPORTED: system-windows
2
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
29
30declare void @g()
31
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: }
65
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: }
111
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: }
119
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
201;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: }
296
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: }
351
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: }
380
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: }
427
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: }
445
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: }
459