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