459 lines · plain
1; UNSUPPORTED: system-windows2 3; RUN: sed -e s/.T1:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK1 %s4; RUN: sed -e s/.T2:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK2 %s5; RUN: sed -e s/.T3:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK3 %s6; RUN: sed -e s/.T4:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK4 %s7; RUN: sed -e s/.T5:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK5 %s8; RUN: sed -e s/.T6:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK6 %s9; RUN: sed -e s/.T7:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK7 %s10; RUN: sed -e s/.T8:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK8 %s11; RUN: sed -e s/.T9:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK9 %s12; RUN: sed -e s/.T10:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK10 %s13; RUN: sed -e s/.T11:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK11 %s14; RUN: sed -e s/.T12:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK12 %s15; RUN: sed -e s/.T13:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK13 %s16; RUN: sed -e s/.T14:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK14 %s17; RUN: sed -e s/.T15:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK15 %s18; RUN: sed -e s/.T16:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK16 %s19; RUN: sed -e s/.T17:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK17 %s20; RUN: sed -e s/.T18:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK18 %s21; RUN: sed -e s/.T19:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK19 %s22; RUN: sed -e s/.T20:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK20 %s23; RUN: sed -e s/.T21:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK21 %s24; RUN: sed -e s/.T22:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK22 %s25; RUN: sed -e s/.T23:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK23 %s26; RUN: sed -e s/.T24:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK24 %s27; RUN: sed -e s/.T25:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK25 %s28; RUN: sed -e s/.T26:// %s | not opt -passes=verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK26 %s29 30declare void @g()31 32;T1: define void @f() {33;T1: entry:34;T1: catchret from undef to label %next35;T1: ; CHECK1: CatchReturnInst needs to be provided a CatchPad36;T1: next:37;T1: unreachable38;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 catchpad44;T2: catchret from %x to label %entry45;T2: ; CHECK2: CatchReturnInst needs to be provided a CatchPad46;T2: }47 48;T3: define void @f() {49;T3: entry:50;T3: cleanupret from undef unwind label %next51;T3: ; CHECK3: CleanupReturnInst needs to be provided a CleanupPad52;T3: next:53;T3: unreachable54;T3: }55 56;T4: define void @f() {57;T4: entry:58;T4: %cs = catchswitch within none [label %next] unwind to caller59;T4: next:60;T4: %x = catchpad within %cs []61;T4: ; cleanupret first operand's operator must be cleanuppad62;T4: cleanupret from %x unwind to caller63;T4: ; CHECK4: CleanupReturnInst needs to be provided a CleanupPad64;T4: }65 66;T5: define void @f() personality ptr @g {67;T5: entry:68;T5: ret void69;T5: switch:70;T5: %cs = catchswitch within none [label %catch] unwind to caller71;T5: catch:72;T5: catchpad within %cs []73;T5: unreachable74;T5: bogus:75;T5: cleanuppad within %cs []76;T5: ; CHECK5: CleanupPadInst has an invalid parent77;T5: unreachable78;T5: }79 80;T6: define void @f() personality ptr @g {81;T6: entry:82;T6: ret void83;T6: switch1:84;T6: %cs1 = catchswitch within none [label %catch1] unwind label %catch285;T6: ; CHECK6: Block containg CatchPadInst must be jumped to only by its catchswitch86;T6: catch1:87;T6: catchpad within %cs1 []88;T6: unreachable89;T6: switch2:90;T6: %cs2 = catchswitch within none [label %catch2] unwind to caller91;T6: catch2:92;T6: catchpad within %cs2 []93;T6: unreachable94;T6: }95 96;T7: define void @f() personality ptr @g {97;T7: entry:98;T7: ret void99;T7: switch1:100;T7: %cs1 = catchswitch within none [label %catch1] unwind to caller101;T7: catch1:102;T7: catchpad within %cs1 []103;T7: unreachable104;T7: switch2:105;T7: %cs2 = catchswitch within %cs1 [label %catch2] unwind to caller106;T7: ; CHECK7: CatchSwitchInst has an invalid parent107;T7: catch2:108;T7: catchpad within %cs2 []109;T7: unreachable110;T7: }111 112;T8: define void @f() personality ptr @g {113;T8: entry:114;T8: ret void115;T8: switch1:116;T8: %cs1 = catchswitch within none [ label %switch1 ] unwind to caller117;T8: ; CHECK8: CatchSwitchInst handlers must be catchpads118;T8: }119 120;T9: define void @f() personality ptr @g {121;T9: entry:122;T9: ret void123;T9: cleanup:124;T9: %cp = cleanuppad within none []125;T9: invoke void @g() [ "funclet"(token %cp) ]126;T9: to label %exit unwind label %cleanup127;T9: ; CHECK9: EH pad cannot handle exceptions raised within it128;T9: ; CHECK9-NEXT: %cp = cleanuppad within none []129;T9: ; CHECK9-NEXT: invoke void @g() [ "funclet"(token %cp) ]130;T9: exit:131;T9: ret void132;T9: }133 134;T10: define void @f() personality ptr @g {135;T10: entry:136;T10: ret void137;T10: cleanup1:138;T10: %cp1 = cleanuppad within none []139;T10: unreachable140;T10: switch:141;T10: %cs = catchswitch within %cp1 [label %catch] unwind to caller142;T10: catch:143;T10: %catchp1 = catchpad within %cs [i32 1]144;T10: unreachable145;T10: cleanup2:146;T10: %cp2 = cleanuppad within %catchp1 []147;T10: unreachable148;T10: cleanup3:149;T10: %cp3 = cleanuppad within %cp2 []150;T10: cleanupret from %cp3 unwind label %switch151;T10: ; CHECK10: EH pad cannot handle exceptions raised within it152;T10: ; CHECK10-NEXT: %cs = catchswitch within %cp1 [label %catch] unwind to caller153;T10: ; CHECK10-NEXT: cleanupret from %cp3 unwind label %switch154;T10: }155 156;T11: define void @f() personality ptr @g {157;T11: entry:158;T11: ret void159;T11: cleanup1:160;T11: %cp1 = cleanuppad within none []161;T11: unreachable162;T11: cleanup2:163;T11: %cp2 = cleanuppad within %cp1 []164;T11: unreachable165;T11: switch:166;T11: %cs = catchswitch within none [label %catch] unwind label %cleanup2167;T11: ; CHECK11: A single unwind edge may only enter one EH pad168;T11: ; CHECK11-NEXT: %cs = catchswitch within none [label %catch] unwind label %cleanup2169;T11: catch:170;T11: catchpad within %cs [i32 1]171;T11: unreachable172;T11: }173 174;T12: define void @f() personality ptr @g {175;T12: entry:176;T12: ret void177;T12: cleanup:178;T12: %cp = cleanuppad within none []179;T12: cleanupret from %cp unwind label %switch180;T12: ; CHECK12: A cleanupret must exit its cleanup181;T12: ; CHECK12-NEXT: cleanupret from %cp unwind label %switch182;T12: switch:183;T12: %cs = catchswitch within %cp [label %catch] unwind to caller184;T12: catch:185;T12: catchpad within %cs [i32 1]186;T12: unreachable187;T12: }188 189;T13: define void @f() personality ptr @g {190;T13: entry:191;T13: ret void192;T13: switch:193;T13: %cs = catchswitch within none [label %catch] unwind label %switch194;T13: ; CHECK13: EH pad cannot handle exceptions raised within it195;T13: ; CHECK13-NEXT: %cs = catchswitch within none [label %catch] unwind label %switch196;T13: catch:197;T13: catchpad within %cs [i32 0]198;T13: unreachable199;T13: }200 201;T14: define void @f() personality ptr @g {202;T14: entry:203;T14: ret void204;T14: cleanup:205;T14: %cp = cleanuppad within none []206;T14: unreachable207;T14: left:208;T14: cleanupret from %cp unwind label %switch209;T14: right:210;T14: cleanupret from %cp unwind to caller211;T14: ; CHECK14: Unwind edges out of a funclet pad must have the same unwind dest212;T14: ; CHECK14-NEXT: %cp = cleanuppad within none []213;T14: ; CHECK14-NEXT: cleanupret from %cp unwind label %switch214;T14: ; CHECK14-NEXT: cleanupret from %cp unwind to caller215;T14: switch:216;T14: %cs = catchswitch within none [label %catch] unwind to caller217;T14: catch:218;T14: catchpad within %cs [i32 1]219;T14: unreachable220;T14: }221 222;T15: define void @f() personality ptr @g {223;T15: entry:224;T15: ret void225;T15: switch:226;T15: %cs = catchswitch within none [label %catch] unwind to caller227;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 %target1231;T15: unreachable:232;T15: unreachable233;T15: target1:234;T15: cleanuppad within none []235;T15: unreachable236;T15: target2:237;T15: cleanuppad within none []238;T15: unreachable239;T15: nested.1:240;T15: %nested.pad.1 = cleanuppad within %catch.pad []241;T15: unreachable242;T15: nested.2:243;T15: %nested.pad.2 = cleanuppad within %nested.pad.1 []244;T15: cleanupret from %nested.pad.2 unwind label %target2245;T15: ; CHECK15: Unwind edges out of a funclet pad must have the same unwind dest246;T15: ; CHECK15-NEXT: %catch.pad = catchpad within %cs [i32 1]247;T15: ; CHECK15-NEXT: cleanupret from %nested.pad.2 unwind label %target2248;T15: ; CHECK15-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]249;T15: ; CHECK15-NEXT: to label %unreachable unwind label %target1250;T15: }251 252;T16: define void @f() personality ptr @g {253;T16: entry:254;T16: ret void255;T16: switch:256;T16: %cs = catchswitch within none [label %catch] unwind to caller257;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 %target1261;T16: ; CHECK16: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch262;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 %target1265;T16: ; CHECK16-NEXT: %cs = catchswitch within none [label %catch] unwind to caller266;T16: unreachable:267;T16: unreachable268;T16: target1:269;T16: cleanuppad within none []270;T16: unreachable271;T16: }272 273;T17: define void @f() personality ptr @g {274;T17: entry:275;T17: ret void276;T17: switch:277;T17: %cs = catchswitch within none [label %catch] unwind label %target1278;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 %target2282;T17: ; CHECK17: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch283;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 %target2286;T17: ; CHECK17-NEXT: %cs = catchswitch within none [label %catch] unwind label %target1287;T17: unreachable:288;T17: unreachable289;T17: target1:290;T17: cleanuppad within none []291;T17: unreachable292;T17: target2:293;T17: cleanuppad within none []294;T17: unreachable295;T17: }296 297;T18: define void @f() personality ptr @g {298;T18: entry:299;T18: invoke void @g()300;T18: to label %invoke.cont unwind label %left301;T18: invoke.cont:302;T18: invoke void @g()303;T18: to label %unreachable unwind label %right304;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 %right308;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 %left312;T18: ; CHECK18: EH pads can't handle each other's exceptions313;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 %right316;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 %left319;T18: unreachable:320;T18: unreachable321;T18: }322 323;T19: define void @f() personality ptr @g {324;T19: entry:325;T19: ret void326;T19: red:327;T19: %redpad = cleanuppad within none []328;T19: unreachable329;T19: red.inner:330;T19: %innerpad = cleanuppad within %redpad []331;T19: invoke void @g() [ "funclet"(token %innerpad) ]332;T19: to label %unreachable unwind label %green333;T19: green:334;T19: %greenswitch = catchswitch within none [label %catch] unwind label %blue335;T19: catch:336;T19: catchpad within %greenswitch [i32 42]337;T19: unreachable338;T19: blue:339;T19: %bluepad = cleanuppad within none []340;T19: cleanupret from %bluepad unwind label %red341;T19: ; CHECK19: EH pads can't handle each other's exceptions342;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 %green345;T19: ; CHECK19-NEXT: %greenswitch = catchswitch within none [label %catch] unwind label %blue346;T19: ; CHECK19-NEXT: %bluepad = cleanuppad within none []347;T19: ; CHECK19-NEXT: cleanupret from %bluepad unwind label %red348;T19: unreachable:349;T19: unreachable350;T19: }351 352;T20: define void @f() personality ptr @g {353;T20: entry:354;T20: ret void355;T20: switch:356;T20: %cs = catchswitch within none [label %catch] unwind label %catch357;T20: ; CHECK20: Catchswitch cannot unwind to one of its catchpads358;T20: ; CHECK20-NEXT: %cs = catchswitch within none [label %catch] unwind label %catch359;T20: ; CHECK20-NEXT: %cp = catchpad within %cs [i32 4]360;T20: catch:361;T20: %cp = catchpad within %cs [i32 4]362;T20: unreachable363;T20: }364 365;T21: define void @f() personality ptr @g {366;T21: entry:367;T21: ret void368;T21: switch:369;T21: %cs = catchswitch within none [label %catch1] unwind label %catch2370;T21: ; CHECK21: Catchswitch cannot unwind to one of its catchpads371;T21: ; CHECK21-NEXT: %cs = catchswitch within none [label %catch1] unwind label %catch2372;T21: ; CHECK21-NEXT: %cp2 = catchpad within %cs [i32 2]373;T21: catch1:374;T21: %cp1 = catchpad within %cs [i32 1]375;T21: unreachable376;T21: catch2:377;T21: %cp2 = catchpad within %cs [i32 2]378;T21: unreachable379;T21: }380 381;T22: define void @f() personality ptr @g {382;T22: invoke void @g()383;T22: to label %merge unwind label %cleanup384;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 %merge389;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 %merge392;T22:393;T22: merge:394;T22: unreachable395;T22: }396 397;T23: define void @f() personality ptr @g {398;T23: invoke void @g()399;T23: to label %exit unwind label %pad400;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: unreachable406;T23:407;T23: exit:408;T23: unreachable409;T23: }410 411;T24: define void @f() personality ptr @g {412;T24: invoke void @g()413;T24: to label %exit unwind label %pad414;T24: ; CHECK24: A single unwind edge may only enter one EH pad415;T24: ; CHECK24: invoke void @g()416;T24: ; CHECK24: to label %exit unwind label %pad417;T24:418;T24: pad:419;T24: %outer = cleanuppad within %outer []420;T24: ; CHECK24: FuncletPadInst must not be nested within itself421;T24: ; CHECK24: %outer = cleanuppad within %outer []422;T24: unreachable423;T24:424;T24: exit:425;T24: unreachable426;T24: }427 428;T25: define void @f() personality ptr @g {429;T25: entry:430;T25: unreachable431;T25:432;T25: catch.dispatch:433;T25: %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup434;T25: ; CHECK25: EH pad jumps through a cycle of pads435;T25: ; CHECK25: %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup436;T25:437;T25: catch:438;T25: %cp2 = catchpad within %cs [ptr null, i32 64, ptr null]439;T25: unreachable440;T25:441;T25: ehcleanup:442;T25: %cp3 = cleanuppad within none []443;T25: cleanupret from %cp3 unwind to caller444;T25: }445 446;T26: define void @f() personality ptr @g {447;T26: entry:448;T26: ret void449;T26:450;T26: ehcleanup:451;T26: cleanuppad within none []452;T26: cleanupret from none unwind label %ehcleanup453;T26: ; CHECK26: A cleanupret must exit its cleanup454;T26: ; CHECK26: cleanupret from none unwind label %ehcleanup455;T26: ; CHECK26: CleanupReturnInst needs to be provided a CleanupPad456;T26: ; CHECK26: cleanupret from none unwind label %ehcleanup457;T26: ; CHECK26: token none458;T26: }459