blob: e5ad2abfb5ed21d2d14cf1d492ca041ee3a6ec59 [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 Tremoulet06125e52016-01-02 15:24:24 +000018
19declare void @g()
David Majnemer8a1c45d2015-12-12 05:38:55 +000020
21;T1: define void @f() {
22;T1: entry:
23;T1: catchret from undef to label %next
24;T1: ; CHECK1: CatchReturnInst needs to be provided a CatchPad
25;T1: next:
26;T1: unreachable
27;T1: }
28
29;T2: define void @f() {
30;T2: entry:
31;T2: %x = cleanuppad within none []
32;T2: ; catchret's first operand's operator must be catchpad
33;T2: catchret from %x to label %entry
34;T2: ; CHECK2: CatchReturnInst needs to be provided a CatchPad
35;T2: }
36
37;T3: define void @f() {
38;T3: entry:
39;T3: cleanupret from undef unwind label %next
40;T3: ; CHECK3: CleanupReturnInst needs to be provided a CleanupPad
41;T3: next:
42;T3: unreachable
43;T3: }
44
45;T4: define void @f() {
46;T4: entry:
47;T4: %cs = catchswitch within none [label %next] unwind to caller
48;T4: next:
49;T4: %x = catchpad within %cs []
50;T4: ; cleanupret first operand's operator must be cleanuppad
51;T4: cleanupret from %x unwind to caller
52;T4: ; CHECK4: CleanupReturnInst needs to be provided a CleanupPad
53;T4: }
Joseph Tremoulet06125e52016-01-02 15:24:24 +000054
55;T5: define void @f() personality void ()* @g {
56;T5: entry:
57;T5: ret void
58;T5: switch:
59;T5: %cs = catchswitch within none [label %catch] unwind to caller
60;T5: catch:
61;T5: catchpad within %cs []
62;T5: unreachable
63;T5: bogus:
64;T5: cleanuppad within %cs []
65;T5: ; CHECK5: CleanupPadInst has an invalid parent
66;T5: unreachable
67;T5: }
68
69;T6: define void @f() personality void ()* @g {
70;T6: entry:
71;T6: ret void
72;T6: switch1:
73;T6: %cs1 = catchswitch within none [label %catch1] unwind label %catch2
74;T6: ; CHECK6: Block containg CatchPadInst must be jumped to only by its catchswitch
75;T6: catch1:
76;T6: catchpad within %cs1 []
77;T6: unreachable
78;T6: switch2:
79;T6: %cs2 = catchswitch within none [label %catch2] unwind to caller
80;T6: catch2:
81;T6: catchpad within %cs2 []
82;T6: unreachable
83;T6: }
84
85;T7: define void @f() personality void ()* @g {
86;T7: entry:
87;T7: ret void
88;T7: switch1:
89;T7: %cs1 = catchswitch within none [label %catch1] unwind to caller
90;T7: catch1:
91;T7: catchpad within %cs1 []
92;T7: unreachable
93;T7: switch2:
94;T7: %cs2 = catchswitch within %cs1 [label %catch2] unwind to caller
95;T7: ; CHECK7: CatchSwitchInst has an invalid parent
96;T7: catch2:
97;T7: catchpad within %cs2 []
98;T7: unreachable
99;T7: }
Joseph Tremoulet131a4622016-01-02 15:25:25 +0000100
101;T8: define void @f() personality void ()* @g {
102;T8: entry:
103;T8: ret void
104;T8: switch1:
105;T8: %cs1 = catchswitch within none [ label %switch1 ] unwind to caller
106;T8: ; CHECK8: CatchSwitchInst handlers must be catchpads
107;T8: }
Joseph Tremoulete28885e2016-01-10 04:28:38 +0000108
109;T9: define void @f() personality void ()* @g {
110;T9: entry:
111;T9: ret void
112;T9: cleanup:
113;T9: %cp = cleanuppad within none []
114;T9: invoke void @g() [ "funclet"(token %cp) ]
115;T9: to label %exit unwind label %cleanup
116;T9: ; CHECK9: EH pad cannot handle exceptions raised within it
117;T9: ; CHECK9-NEXT: %cp = cleanuppad within none []
118;T9: ; CHECK9-NEXT: invoke void @g() [ "funclet"(token %cp) ]
119;T9: exit:
120;T9: ret void
121;T9: }
122
123;T10: define void @f() personality void ()* @g {
124;T10: entry:
125;T10: ret void
126;T10: cleanup1:
127;T10: %cp1 = cleanuppad within none []
128;T10: unreachable
129;T10: switch:
130;T10: %cs = catchswitch within %cp1 [label %catch] unwind to caller
131;T10: catch:
132;T10: %catchp1 = catchpad within %cs [i32 1]
133;T10: unreachable
134;T10: cleanup2:
135;T10: %cp2 = cleanuppad within %catchp1 []
136;T10: unreachable
137;T10: cleanup3:
138;T10: %cp3 = cleanuppad within %cp2 []
139;T10: cleanupret from %cp3 unwind label %switch
140;T10: ; CHECK10: EH pad cannot handle exceptions raised within it
141;T10: ; CHECK10-NEXT: %cs = catchswitch within %cp1 [label %catch] unwind to caller
142;T10: ; CHECK10-NEXT: cleanupret from %cp3 unwind label %switch
143;T10: }
144
145;T11: define void @f() personality void ()* @g {
146;T11: entry:
147;T11: ret void
148;T11: cleanup1:
149;T11: %cp1 = cleanuppad within none []
150;T11: unreachable
151;T11: cleanup2:
152;T11: %cp2 = cleanuppad within %cp1 []
153;T11: unreachable
154;T11: switch:
155;T11: %cs = catchswitch within none [label %catch] unwind label %cleanup2
156;T11: ; CHECK11: A single unwind edge may only enter one EH pad
157;T11: ; CHECK11-NEXT: %cs = catchswitch within none [label %catch] unwind label %cleanup2
158;T11: catch:
159;T11: catchpad within %cs [i32 1]
160;T11: unreachable
161;T11: }
162
163;T12: define void @f() personality void ()* @g {
164;T12: entry:
165;T12: ret void
166;T12: cleanup:
167;T12: %cp = cleanuppad within none []
168;T12: cleanupret from %cp unwind label %switch
169;T12: ; CHECK12: A cleanupret must exit its cleanup
170;T12: ; CHECK12-NEXT: cleanupret from %cp unwind label %switch
171;T12: switch:
172;T12: %cs = catchswitch within %cp [label %catch] unwind to caller
173;T12: catch:
174;T12: catchpad within %cs [i32 1]
175;T12: unreachable
176;T12: }
177
178;T13: define void @f() personality void ()* @g {
179;T13: entry:
180;T13: ret void
181;T13: switch:
182;T13: %cs = catchswitch within none [label %catch] unwind label %switch
183;T13: ; CHECK13: EH pad cannot handle exceptions raised within it
184;T13: ; CHECK13-NEXT: %cs = catchswitch within none [label %catch] unwind label %switch
185;T13: catch:
186;T13: catchpad within %cs [i32 0]
187;T13: unreachable
188;T13: }
189
Joseph Tremoulet81e81962016-01-10 04:30:02 +0000190;T14: define void @f() personality void ()* @g {
191;T14: entry:
192;T14: ret void
193;T14: cleanup:
194;T14: %cp = cleanuppad within none []
195;T14: unreachable
196;T14: left:
197;T14: cleanupret from %cp unwind label %switch
198;T14: right:
199;T14: cleanupret from %cp unwind to caller
200;T14: ; CHECK14: Unwind edges out of a funclet pad must have the same unwind dest
201;T14: ; CHECK14-NEXT: %cp = cleanuppad within none []
202;T14: ; CHECK14-NEXT: cleanupret from %cp unwind label %switch
203;T14: ; CHECK14-NEXT: cleanupret from %cp unwind to caller
204;T14: switch:
205;T14: %cs = catchswitch within none [label %catch] unwind to caller
206;T14: catch:
207;T14: catchpad within %cs [i32 1]
208;T14: unreachable
209;T14: }
210
211;T15: define void @f() personality void ()* @g {
212;T15: entry:
213;T15: ret void
214;T15: switch:
215;T15: %cs = catchswitch within none [label %catch] unwind to caller
216;T15: catch:
217;T15: %catch.pad = catchpad within %cs [i32 1]
218;T15: invoke void @g() [ "funclet"(token %catch.pad) ]
219;T15: to label %unreachable unwind label %target1
220;T15: unreachable:
221;T15: unreachable
222;T15: target1:
223;T15: cleanuppad within none []
224;T15: unreachable
225;T15: target2:
226;T15: cleanuppad within none []
227;T15: unreachable
228;T15: nested.1:
229;T15: %nested.pad.1 = cleanuppad within %catch.pad []
230;T15: unreachable
231;T15: nested.2:
232;T15: %nested.pad.2 = cleanuppad within %nested.pad.1 []
233;T15: cleanupret from %nested.pad.2 unwind label %target2
234;T15: ; CHECK15: Unwind edges out of a funclet pad must have the same unwind dest
235;T15: ; CHECK15-NEXT: %catch.pad = catchpad within %cs [i32 1]
236;T15: ; CHECK15-NEXT: cleanupret from %nested.pad.2 unwind label %target2
237;T15: ; CHECK15-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
238;T15: ; CHECK15-NEXT: to label %unreachable unwind label %target1
239;T15: }
240
241;T16: define void @f() personality void ()* @g {
242;T16: entry:
243;T16: ret void
244;T16: switch:
245;T16: %cs = catchswitch within none [label %catch] unwind to caller
246;T16: catch:
247;T16: %catch.pad = catchpad within %cs [i32 1]
248;T16: invoke void @g() [ "funclet"(token %catch.pad) ]
249;T16: to label %unreachable unwind label %target1
250;T16: ; CHECK16: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
251;T16: ; CHECK16-NEXT: %catch.pad = catchpad within %cs [i32 1]
252;T16: ; CHECK16-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
253;T16: ; CHECK16-NEXT: to label %unreachable unwind label %target1
254;T16: ; CHECK16-NEXT: %cs = catchswitch within none [label %catch] unwind to caller
255;T16: unreachable:
256;T16: unreachable
257;T16: target1:
258;T16: cleanuppad within none []
259;T16: unreachable
260;T16: }
261
262;T17: define void @f() personality void ()* @g {
263;T17: entry:
264;T17: ret void
265;T17: switch:
266;T17: %cs = catchswitch within none [label %catch] unwind label %target1
267;T17: catch:
268;T17: %catch.pad = catchpad within %cs [i32 1]
269;T17: invoke void @g() [ "funclet"(token %catch.pad) ]
270;T17: to label %unreachable unwind label %target2
271;T17: ; CHECK17: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
272;T17: ; CHECK17-NEXT: %catch.pad = catchpad within %cs [i32 1]
273;T17: ; CHECK17-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
274;T17: ; CHECK17-NEXT: to label %unreachable unwind label %target2
275;T17: ; CHECK17-NEXT: %cs = catchswitch within none [label %catch] unwind label %target1
276;T17: unreachable:
277;T17: unreachable
278;T17: target1:
279;T17: cleanuppad within none []
280;T17: unreachable
281;T17: target2:
282;T17: cleanuppad within none []
283;T17: unreachable
284;T17: }