1 // Copyright (c) Microsoft. All rights reserved. 2 // Licensed under the MIT license. See LICENSE file in the project root for 3 // full license information. 4 5 /* 6 * Exercise lots of different kinds of C++ EH frames. Compile this with 7 * every combination of opts you can to stress the C++ EH frame code in the 8 * backend. 9 */ 10 11 #include <stdio.h> 12 #include <malloc.h> 13 #include <stdarg.h> 14 #include <memory.h> 15 16 #ifndef ALIGN 17 #define ALIGN 64 18 #endif 19 20 #define ARG(x) &x, sizeof(x) 21 #define ARG2(x) ARG(x), ARG(x) 22 #define ARG5(x) ARG(x), ARG(x), ARG(x), ARG(x), ARG(x) 23 24 extern int TestFunc(int, ...); 25 26 int failures; 27 28 int one = 1; 29 int zero = 0; 30 31 size_t global = 16; 32 volatile bool TestFuncThrows; 33 34 struct SmallObj { 35 int x; 36 }; 37 38 struct BigObj { 39 char x[1024]; 40 }; 41 42 int Simple(int arg) { 43 puts(__FUNCTION__); 44 int res = 0; 45 SmallObj f; 46 __try { TestFunc(1, ARG(f), ARG(res), ARG(arg), NULL); } 47 __finally { res = TestFunc(1, ARG(f), ARG(res), ARG(arg), NULL); } 48 return res; 49 } 50 51 int Try(int arg) { 52 puts(__FUNCTION__); 53 int res = 0; 54 SmallObj f; 55 __try { res = TestFunc(1, ARG(f), ARG(res), ARG(arg), NULL); } 56 __except(TestFunc(2, ARG(f), ARG(res), ARG(arg), NULL), zero) { 57 res = TestFunc(2, ARG(f), ARG(res), ARG(arg), NULL); 58 } 59 return res; 60 } 61 62 int GSCookie(int arg) { 63 puts(__FUNCTION__); 64 int res = 0; 65 char buf[16]; 66 SmallObj f; 67 __try { TestFunc(1, ARG(buf), ARG(f), ARG(res), ARG(arg), NULL); } 68 __finally { res = TestFunc(1, ARG(buf), ARG(f), ARG(res), ARG(arg), NULL); } 69 return res; 70 } 71 72 int TryAndGSCookie(int arg) { 73 puts(__FUNCTION__); 74 int res = 0; 75 char buf[16]; 76 SmallObj f; 77 __try { res = TestFunc(1, ARG(buf), ARG(f), ARG(res), ARG(arg), NULL); } 78 __except(TestFunc(2, ARG(buf), ARG(f), ARG(res), ARG(arg), NULL), zero) { 79 res = TestFunc(2, ARG(buf), ARG(f), ARG(res), ARG(arg), NULL); 80 } 81 return res; 82 } 83 84 int Align(int arg) { 85 puts(__FUNCTION__); 86 int res = 0; 87 __declspec(align(ALIGN)) double d[4]; 88 SmallObj f; 89 __try { TestFunc(1, ARG(d), ARG(f), ARG(res), ARG(arg), NULL); } 90 __finally { res = TestFunc(1, ARG(d), ARG(f), ARG(res), ARG(arg), NULL); } 91 return res; 92 } 93 94 int TryAndAlign(int arg) { 95 puts(__FUNCTION__); 96 int res = 0; 97 __declspec(align(ALIGN)) double d[4]; 98 SmallObj f; 99 __try { res = TestFunc(1, ARG(d), ARG(f), ARG(res), ARG(arg), NULL); } 100 __except(TestFunc(2, ARG(d), ARG(f), ARG(res), ARG(arg), NULL), zero) { 101 res = TestFunc(2, ARG(d), ARG(f), ARG(res), ARG(arg), NULL); 102 } 103 return res; 104 } 105 106 int GSCookieAndAlign(int arg) { 107 puts(__FUNCTION__); 108 int res = 0; 109 char buf[16]; 110 __declspec(align(ALIGN)) double d[4]; 111 SmallObj f; 112 __try { TestFunc(1, ARG(buf), ARG(d), ARG(f), ARG(res), ARG(arg), NULL); } 113 __finally { 114 res = TestFunc(1, ARG(buf), ARG(d), ARG(f), ARG(res), ARG(arg), NULL); 115 } 116 return res; 117 } 118 119 int TryAndGSCookieAndAlign(int arg) { 120 puts(__FUNCTION__); 121 int res = 0; 122 char buf[16]; 123 __declspec(align(ALIGN)) double d[4]; 124 SmallObj f; 125 __try { 126 res = TestFunc(1, ARG(buf), ARG(d), ARG(f), ARG(res), ARG(arg), NULL); 127 } 128 __except(TestFunc(2, ARG(buf), ARG(d), ARG(f), ARG(res), ARG(arg), NULL), 129 zero) { 130 res = TestFunc(2, ARG(buf), ARG(d), ARG(f), ARG(res), ARG(arg), NULL); 131 } 132 return res; 133 } 134 135 int Alloca(int arg) { 136 puts(__FUNCTION__); 137 int res = 0; 138 SmallObj f; 139 __try { 140 TestFunc(1, _alloca(global), global, ARG(f), ARG(res), ARG(arg), NULL); 141 } 142 __finally { res = TestFunc(1, ARG(f), ARG(res), ARG(arg), NULL); } 143 return res; 144 } 145 146 int TryAndAlloca(int arg) { 147 puts(__FUNCTION__); 148 int res = 0; 149 SmallObj f; 150 __try { 151 res = 152 TestFunc(1, _alloca(global), global, ARG(f), ARG(res), ARG(arg), NULL); 153 } 154 __except(TestFunc(2, ARG(f), ARG(res), ARG(arg), NULL), zero) { 155 res = TestFunc(2, ARG(f), ARG(res), ARG(arg), NULL); 156 } 157 return res; 158 } 159 160 int GSCookieAndAlloca(int arg) { 161 puts(__FUNCTION__); 162 int res = 0; 163 char buf[16]; 164 SmallObj f; 165 __try { 166 TestFunc(1, ARG(buf), _alloca(global), global, ARG(f), ARG(res), ARG(arg), 167 NULL); 168 } 169 __finally { res = TestFunc(1, ARG(buf), ARG(f), ARG(res), ARG(arg), NULL); } 170 return res; 171 } 172 173 int TryAndGSCookieAndAlloca(int arg) { 174 puts(__FUNCTION__); 175 int res = 0; 176 char buf[16]; 177 SmallObj f; 178 __try { 179 res = TestFunc(1, ARG(buf), _alloca(global), global, ARG(f), ARG(res), 180 ARG(arg), NULL); 181 } 182 __except(TestFunc(2, ARG(buf), ARG(f), ARG(res), ARG(arg), NULL), zero) { 183 res = TestFunc(2, ARG(buf), ARG(f), ARG(res), ARG(arg), NULL); 184 } 185 return res; 186 } 187 188 int AlignAndAlloca(int arg) { 189 puts(__FUNCTION__); 190 int res = 0; 191 __declspec(align(ALIGN)) double d[4]; 192 SmallObj f; 193 __try { 194 TestFunc(1, ARG(d), _alloca(global), global, ARG(f), ARG(res), ARG(arg), 195 NULL); 196 } 197 __finally { res = TestFunc(1, ARG(d), ARG(f), ARG(res), ARG(arg), NULL); } 198 return res; 199 } 200 201 int TryAndAlignAndAlloca(int arg) { 202 puts(__FUNCTION__); 203 int res = 0; 204 __declspec(align(ALIGN)) double d[4]; 205 SmallObj f; 206 __try { 207 res = TestFunc(1, ARG(d), _alloca(global), global, ARG(f), ARG(res), 208 ARG(arg), NULL); 209 } 210 __except(TestFunc(2, ARG(d), ARG(f), ARG(res), ARG(arg), NULL), zero) { 211 res = TestFunc(2, ARG(d), ARG(f), ARG(res), ARG(arg), NULL); 212 } 213 return res; 214 } 215 216 int GSCookieAndAlignAndAlloca(int arg) { 217 puts(__FUNCTION__); 218 int res = 0; 219 char buf[16]; 220 __declspec(align(ALIGN)) double d[4]; 221 SmallObj f; 222 __try { 223 TestFunc(1, ARG(buf), ARG(d), _alloca(global), global, ARG(f), ARG(res), 224 ARG(arg), NULL); 225 } 226 __finally { 227 res = TestFunc(1, ARG(buf), ARG(d), ARG(f), ARG(res), ARG(arg), NULL); 228 } 229 return res; 230 } 231 232 int TryAndGSCookieAndAlignAndAlloca(int arg) { 233 puts(__FUNCTION__); 234 int res = 0; 235 char buf[16]; 236 __declspec(align(ALIGN)) double d[4]; 237 SmallObj f; 238 __try { 239 res = TestFunc(1, ARG(buf), ARG(d), _alloca(global), global, ARG(f), 240 ARG(res), ARG(arg), NULL); 241 } 242 __except(TestFunc(2, ARG(buf), ARG(d), ARG(f), ARG(res), ARG(arg), NULL), 243 zero) { 244 res = TestFunc(2, ARG(buf), ARG(d), ARG(f), ARG(res), ARG(arg), NULL); 245 } 246 return res; 247 } 248 249 /* 250 * The BigLocals variants try to trigger EBP adjustment, and generally do in 251 * the /O1 case for the non-aligned stacks. 252 */ 253 254 int BigLocals(int arg) { 255 puts(__FUNCTION__); 256 int res = 0; 257 BigObj f1; 258 __try { TestFunc(1, ARG(f1), ARG5(res), ARG(arg), NULL); } 259 __finally { res = TestFunc(1, ARG(f1), ARG5(res), ARG(arg), NULL); } 260 return res; 261 } 262 263 int TryAndBigLocals(int arg) { 264 puts(__FUNCTION__); 265 int res = 0; 266 BigObj f1; 267 __try { res = TestFunc(1, ARG(f1), ARG5(res), ARG(arg), NULL); } 268 __except(TestFunc(2, ARG(f1), ARG5(res), ARG(arg), NULL), zero) { 269 res = TestFunc(2, ARG(f1), ARG5(res), ARG(arg), NULL); 270 } 271 return res; 272 } 273 274 int GSCookieAndBigLocals(int arg) { 275 puts(__FUNCTION__); 276 int res = 0; 277 char buf[16]; 278 BigObj f1; 279 __try { TestFunc(1, ARG(buf), ARG(f1), ARG5(res), ARG(arg), NULL); } 280 __finally { res = TestFunc(1, ARG(buf), ARG(f1), ARG5(res), ARG(arg), NULL); } 281 return res; 282 } 283 284 int TryAndGSCookieAndBigLocals(int arg) { 285 puts(__FUNCTION__); 286 int res = 0; 287 char buf[16]; 288 BigObj f1; 289 __try { res = TestFunc(1, ARG(buf), ARG(f1), ARG5(res), ARG(arg), NULL); } 290 __except(TestFunc(2, ARG(buf), ARG(f1), ARG5(res), ARG(arg), NULL), zero) { 291 res = TestFunc(2, ARG(buf), ARG(f1), ARG5(res), ARG(arg), NULL); 292 } 293 return res; 294 } 295 296 int AlignAndBigLocals(int arg) { 297 puts(__FUNCTION__); 298 int res = 0; 299 __declspec(align(ALIGN)) double d[4]; 300 BigObj f1; 301 __try { TestFunc(1, ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); } 302 __finally { res = TestFunc(1, ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); } 303 return res; 304 } 305 306 int TryAndAlignAndBigLocals(int arg) { 307 puts(__FUNCTION__); 308 int res = 0; 309 __declspec(align(ALIGN)) double d[4]; 310 BigObj f1; 311 __try { res = TestFunc(1, ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); } 312 __except(TestFunc(2, ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL), zero) { 313 res = TestFunc(2, ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); 314 } 315 return res; 316 } 317 318 int GSCookieAndAlignAndBigLocals(int arg) { 319 puts(__FUNCTION__); 320 int res = 0; 321 char buf[16]; 322 __declspec(align(ALIGN)) double d[4]; 323 BigObj f1; 324 __try { TestFunc(1, ARG(buf), ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); } 325 __finally { 326 res = TestFunc(1, ARG(buf), ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); 327 } 328 return res; 329 } 330 331 int TryAndGSCookieAndAlignAndBigLocals(int arg) { 332 puts(__FUNCTION__); 333 int res = 0; 334 char buf[16]; 335 __declspec(align(ALIGN)) double d[4]; 336 BigObj f1; 337 __try { 338 res = TestFunc(1, ARG(buf), ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); 339 } 340 __except(TestFunc(2, ARG(buf), ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL), 341 zero) { 342 res = TestFunc(2, ARG(buf), ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); 343 } 344 return res; 345 } 346 347 int AllocaAndBigLocals(int arg) { 348 puts(__FUNCTION__); 349 int res = 0; 350 BigObj f1; 351 __try { 352 TestFunc(1, _alloca(global), global, ARG(f1), ARG5(res), ARG(arg), NULL); 353 } 354 __finally { res = TestFunc(1, ARG(f1), ARG5(res), ARG(arg), NULL); } 355 return res; 356 } 357 358 int TryAndAllocaAndBigLocals(int arg) { 359 puts(__FUNCTION__); 360 int res = 0; 361 BigObj f1; 362 __try { 363 res = TestFunc(1, _alloca(global), global, ARG(f1), ARG5(res), ARG(arg), 364 NULL); 365 } 366 __except(TestFunc(2, ARG(f1), ARG5(res), ARG(arg), NULL), zero) { 367 res = TestFunc(2, ARG(f1), ARG5(res), ARG(arg), NULL); 368 } 369 return res; 370 } 371 372 int GSCookieAndAllocaAndBigLocals(int arg) { 373 puts(__FUNCTION__); 374 int res = 0; 375 char buf[16]; 376 BigObj f1; 377 __try { 378 TestFunc(1, ARG(buf), _alloca(global), global, ARG(f1), ARG5(res), ARG(arg), 379 NULL); 380 } 381 __finally { res = TestFunc(1, ARG(buf), ARG(f1), ARG5(res), ARG(arg), NULL); } 382 return res; 383 } 384 385 int TryAndGSCookieAndAllocaAndBigLocals(int arg) { 386 puts(__FUNCTION__); 387 int res = 0; 388 char buf[16]; 389 BigObj f1; 390 __try { 391 res = TestFunc(1, ARG(buf), _alloca(global), global, ARG(f1), ARG5(res), 392 ARG(arg), NULL); 393 } 394 __except(TestFunc(2, ARG(buf), ARG(f1), ARG5(res), ARG(arg), NULL), zero) { 395 res = TestFunc(2, ARG(buf), ARG(f1), ARG5(res), ARG(arg), NULL); 396 } 397 return res; 398 } 399 400 int AlignAndAllocaAndBigLocals(int arg) { 401 puts(__FUNCTION__); 402 int res = 0; 403 __declspec(align(ALIGN)) double d[4]; 404 BigObj f1; 405 __try { 406 TestFunc(1, ARG(d), _alloca(global), global, ARG(f1), ARG5(res), ARG(arg), 407 NULL); 408 } 409 __finally { res = TestFunc(1, ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); } 410 return res; 411 } 412 413 int TryAndAlignAndAllocaAndBigLocals(int arg) { 414 puts(__FUNCTION__); 415 int res = 0; 416 __declspec(align(ALIGN)) double d[4]; 417 BigObj f1; 418 __try { 419 res = TestFunc(1, ARG(d), _alloca(global), global, ARG(f1), ARG5(res), 420 ARG(arg), NULL); 421 } 422 __except(TestFunc(2, ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL), zero) { 423 res = TestFunc(2, ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); 424 } 425 return res; 426 } 427 428 int GSCookieAndAlignAndAllocaAndBigLocals(int arg) { 429 puts(__FUNCTION__); 430 int res = 0; 431 char buf[16]; 432 __declspec(align(ALIGN)) double d[4]; 433 BigObj f1; 434 __try { 435 TestFunc(1, ARG(buf), ARG(d), _alloca(global), global, ARG(f1), ARG5(res), 436 ARG(arg), NULL); 437 } 438 __finally { 439 res = TestFunc(1, ARG(buf), ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); 440 } 441 return res; 442 } 443 444 int TryAndGSCookieAndAlignAndAllocaAndBigLocals(int arg) { 445 puts(__FUNCTION__); 446 int res = 0; 447 char buf[16]; 448 __declspec(align(ALIGN)) double d[4]; 449 BigObj f1; 450 __try { 451 res = TestFunc(1, ARG(buf), ARG(d), _alloca(global), global, ARG(f1), 452 ARG5(res), ARG(arg), NULL); 453 } 454 __except(TestFunc(2, ARG(buf), ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL), 455 zero) { 456 res = TestFunc(2, ARG(buf), ARG(d), ARG(f1), ARG5(res), ARG(arg), NULL); 457 } 458 return res; 459 } 460 461 /* 462 * The EbpAdj variants try to trigger EBP adjustment, and generally do in 463 * the /O1 case for the non-aligned stacks. They add a non-GS-protected 464 * buffer so the EH node is far from both sides of the local variable 465 * allocation. Doesn't seem to add any testing over what the BigLocals cases 466 * already do. 467 */ 468 469 int EbpAdj(int arg) { 470 puts(__FUNCTION__); 471 int res = 0; 472 int a[512]; 473 BigObj f1; 474 __try { TestFunc(1, ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); } 475 __finally { res = TestFunc(1, ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); } 476 return res; 477 } 478 479 int TryAndEbpAdj(int arg) { 480 puts(__FUNCTION__); 481 int res = 0; 482 int a[512]; 483 BigObj f1; 484 __try { res = TestFunc(1, ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); } 485 __except(TestFunc(2, ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL), zero) { 486 res = TestFunc(2, ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 487 } 488 return res; 489 } 490 491 int GSCookieAndEbpAdj(int arg) { 492 puts(__FUNCTION__); 493 int res = 0; 494 int a[512]; 495 char buf[16]; 496 BigObj f1; 497 __try { TestFunc(1, ARG(buf), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); } 498 __finally { 499 res = TestFunc(1, ARG(buf), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 500 } 501 return res; 502 } 503 504 int TryAndGSCookieAndEbpAdj(int arg) { 505 puts(__FUNCTION__); 506 int res = 0; 507 int a[512]; 508 char buf[16]; 509 BigObj f1; 510 __try { 511 res = TestFunc(1, ARG(buf), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 512 } 513 __except(TestFunc(2, ARG(buf), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL), 514 zero) { 515 res = TestFunc(2, ARG(buf), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 516 } 517 return res; 518 } 519 520 int AlignAndEbpAdj(int arg) { 521 puts(__FUNCTION__); 522 int res = 0; 523 int a[512]; 524 __declspec(align(ALIGN)) double d[4]; 525 BigObj f1; 526 __try { TestFunc(1, ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); } 527 __finally { 528 res = TestFunc(1, ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 529 } 530 return res; 531 } 532 533 int TryAndAlignAndEbpAdj(int arg) { 534 puts(__FUNCTION__); 535 int res = 0; 536 int a[512]; 537 __declspec(align(ALIGN)) double d[4]; 538 BigObj f1; 539 __try { 540 res = TestFunc(1, ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 541 } 542 __except(TestFunc(2, ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL), 543 zero) { 544 res = TestFunc(2, ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 545 } 546 return res; 547 } 548 549 int GSCookieAndAlignAndEbpAdj(int arg) { 550 puts(__FUNCTION__); 551 int res = 0; 552 int a[512]; 553 char buf[16]; 554 __declspec(align(ALIGN)) double d[4]; 555 BigObj f1; 556 __try { 557 TestFunc(1, ARG(buf), ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 558 } 559 __finally { 560 res = TestFunc(1, ARG(buf), ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), 561 NULL); 562 } 563 return res; 564 } 565 566 int TryAndGSCookieAndAlignAndEbpAdj(int arg) { 567 puts(__FUNCTION__); 568 int res = 0; 569 int a[512]; 570 char buf[16]; 571 __declspec(align(ALIGN)) double d[4]; 572 BigObj f1; 573 __try { 574 res = TestFunc(1, ARG(buf), ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), 575 NULL); 576 } 577 __except(TestFunc(2, ARG(buf), ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), 578 NULL), 579 zero) { 580 res = TestFunc(2, ARG(buf), ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), 581 NULL); 582 } 583 return res; 584 } 585 586 int AllocaAndEbpAdj(int arg) { 587 puts(__FUNCTION__); 588 int res = 0; 589 int a[512]; 590 BigObj f1; 591 __try { 592 TestFunc(1, _alloca(global), global, ARG(f1), ARG2(a), ARG5(res), ARG(arg), 593 NULL); 594 } 595 __finally { res = TestFunc(1, ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); } 596 return res; 597 } 598 599 int TryAndAllocaAndEbpAdj(int arg) { 600 puts(__FUNCTION__); 601 int res = 0; 602 int a[512]; 603 BigObj f1; 604 __try { 605 res = TestFunc(1, _alloca(global), global, ARG(f1), ARG2(a), ARG5(res), 606 ARG(arg), NULL); 607 } 608 __except(TestFunc(2, ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL), zero) { 609 res = TestFunc(2, ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 610 } 611 return res; 612 } 613 614 int GSCookieAndAllocaAndEbpAdj(int arg) { 615 puts(__FUNCTION__); 616 int res = 0; 617 int a[512]; 618 char buf[16]; 619 BigObj f1; 620 __try { 621 TestFunc(1, ARG(buf), _alloca(global), global, ARG(f1), ARG2(a), ARG5(res), 622 ARG(arg), NULL); 623 } 624 __finally { 625 res = TestFunc(1, ARG(buf), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 626 } 627 return res; 628 } 629 630 int TryAndGSCookieAndAllocaAndEbpAdj(int arg) { 631 puts(__FUNCTION__); 632 int res = 0; 633 int a[512]; 634 char buf[16]; 635 BigObj f1; 636 __try { 637 res = TestFunc(1, ARG(buf), _alloca(global), global, ARG(f1), ARG2(a), 638 ARG5(res), ARG(arg), NULL); 639 } 640 __except(TestFunc(2, ARG(buf), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL), 641 zero) { 642 res = TestFunc(2, ARG(buf), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 643 } 644 return res; 645 } 646 647 int AlignAndAllocaAndEbpAdj(int arg) { 648 puts(__FUNCTION__); 649 int res = 0; 650 int a[512]; 651 __declspec(align(ALIGN)) double d[4]; 652 BigObj f1; 653 __try { 654 TestFunc(1, ARG(d), _alloca(global), global, ARG(f1), ARG2(a), ARG5(res), 655 ARG(arg), NULL); 656 } 657 __finally { 658 res = TestFunc(1, ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 659 } 660 return res; 661 } 662 663 int TryAndAlignAndAllocaAndEbpAdj(int arg) { 664 puts(__FUNCTION__); 665 int res = 0; 666 int a[512]; 667 __declspec(align(ALIGN)) double d[4]; 668 BigObj f1; 669 __try { 670 res = TestFunc(1, ARG(d), _alloca(global), global, ARG(f1), ARG2(a), 671 ARG5(res), ARG(arg), NULL); 672 } 673 __except(TestFunc(2, ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL), 674 zero) { 675 res = TestFunc(2, ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), NULL); 676 } 677 return res; 678 } 679 680 int GSCookieAndAlignAndAllocaAndEbpAdj(int arg) { 681 puts(__FUNCTION__); 682 int res = 0; 683 int a[512]; 684 char buf[16]; 685 __declspec(align(ALIGN)) double d[4]; 686 BigObj f1; 687 __try { 688 TestFunc(1, ARG(buf), ARG(d), _alloca(global), global, ARG(f1), ARG2(a), 689 ARG5(res), ARG(arg), NULL); 690 } 691 __finally { 692 res = TestFunc(1, ARG(buf), ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), 693 NULL); 694 } 695 return res; 696 } 697 698 int TryAndGSCookieAndAlignAndAllocaAndEbpAdj(int arg) { 699 puts(__FUNCTION__); 700 int res = 0; 701 int a[512]; 702 char buf[16]; 703 __declspec(align(ALIGN)) double d[4]; 704 BigObj f1; 705 __try { 706 res = TestFunc(1, ARG(buf), ARG(d), _alloca(global), global, ARG(f1), 707 ARG2(a), ARG5(res), ARG(arg), NULL); 708 } 709 __except(TestFunc(2, ARG(buf), ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), 710 NULL), 711 zero) { 712 res = TestFunc(2, ARG(buf), ARG(d), ARG(f1), ARG2(a), ARG5(res), ARG(arg), 713 NULL); 714 } 715 return res; 716 } 717 718 __declspec(noinline) int TestFunc(int x, ...) { 719 va_list ap; 720 va_start(ap, x); 721 722 for (;;) { 723 void *pbuf = va_arg(ap, void *); 724 if (pbuf == NULL) { 725 break; 726 } 727 size_t len = va_arg(ap, size_t); 728 memset(pbuf, 0, len); 729 } 730 731 if (TestFuncThrows) { 732 TestFuncThrows = false; 733 *(volatile int *)0; 734 } 735 736 return static_cast<int>(global); 737 } 738 739 void RunTests() { 740 puts("Test pass 1 - no exceptions"); 741 742 __try { 743 Simple(1); 744 Try(1); 745 GSCookie(1); 746 TryAndGSCookie(1); 747 Align(1); 748 TryAndAlign(1); 749 GSCookieAndAlign(1); 750 TryAndGSCookieAndAlign(1); 751 Alloca(1); 752 TryAndAlloca(1); 753 GSCookieAndAlloca(1); 754 TryAndGSCookieAndAlloca(1); 755 AlignAndAlloca(1); 756 TryAndAlignAndAlloca(1); 757 GSCookieAndAlignAndAlloca(1); 758 TryAndGSCookieAndAlignAndAlloca(1); 759 BigLocals(1); 760 TryAndBigLocals(1); 761 GSCookieAndBigLocals(1); 762 TryAndGSCookieAndBigLocals(1); 763 AlignAndBigLocals(1); 764 TryAndAlignAndBigLocals(1); 765 GSCookieAndAlignAndBigLocals(1); 766 TryAndGSCookieAndAlignAndBigLocals(1); 767 AllocaAndBigLocals(1); 768 TryAndAllocaAndBigLocals(1); 769 GSCookieAndAllocaAndBigLocals(1); 770 TryAndGSCookieAndAllocaAndBigLocals(1); 771 AlignAndAllocaAndBigLocals(1); 772 TryAndAlignAndAllocaAndBigLocals(1); 773 GSCookieAndAlignAndAllocaAndBigLocals(1); 774 TryAndGSCookieAndAlignAndAllocaAndBigLocals(1); 775 EbpAdj(1); 776 TryAndEbpAdj(1); 777 GSCookieAndEbpAdj(1); 778 TryAndGSCookieAndEbpAdj(1); 779 AlignAndEbpAdj(1); 780 TryAndAlignAndEbpAdj(1); 781 GSCookieAndAlignAndEbpAdj(1); 782 TryAndGSCookieAndAlignAndEbpAdj(1); 783 AllocaAndEbpAdj(1); 784 TryAndAllocaAndEbpAdj(1); 785 GSCookieAndAllocaAndEbpAdj(1); 786 TryAndGSCookieAndAllocaAndEbpAdj(1); 787 AlignAndAllocaAndEbpAdj(1); 788 TryAndAlignAndAllocaAndEbpAdj(1); 789 GSCookieAndAlignAndAllocaAndEbpAdj(1); 790 TryAndGSCookieAndAlignAndAllocaAndEbpAdj(1); 791 } 792 __except(one) { 793 puts("ERROR - exception not expected"); 794 ++failures; 795 } 796 797 puts("Test pass 2 - exceptions"); 798 799 for (int i = 0; i < 48; ++i) { 800 TestFuncThrows = true; 801 bool caught = false; 802 __try { 803 switch (i) { 804 case 0: 805 Simple(1); 806 break; 807 case 1: 808 Try(1); 809 break; 810 case 2: 811 GSCookie(1); 812 break; 813 case 3: 814 TryAndGSCookie(1); 815 break; 816 case 4: 817 Align(1); 818 break; 819 case 5: 820 TryAndAlign(1); 821 break; 822 case 6: 823 GSCookieAndAlign(1); 824 break; 825 case 7: 826 TryAndGSCookieAndAlign(1); 827 break; 828 case 8: 829 Alloca(1); 830 break; 831 case 9: 832 TryAndAlloca(1); 833 break; 834 case 10: 835 GSCookieAndAlloca(1); 836 break; 837 case 11: 838 TryAndGSCookieAndAlloca(1); 839 break; 840 case 12: 841 AlignAndAlloca(1); 842 break; 843 case 13: 844 TryAndAlignAndAlloca(1); 845 break; 846 case 14: 847 GSCookieAndAlignAndAlloca(1); 848 break; 849 case 15: 850 TryAndGSCookieAndAlignAndAlloca(1); 851 break; 852 case 16: 853 BigLocals(1); 854 break; 855 case 17: 856 TryAndBigLocals(1); 857 break; 858 case 18: 859 GSCookieAndBigLocals(1); 860 break; 861 case 19: 862 TryAndGSCookieAndBigLocals(1); 863 break; 864 case 20: 865 AlignAndBigLocals(1); 866 break; 867 case 21: 868 TryAndAlignAndBigLocals(1); 869 break; 870 case 22: 871 GSCookieAndAlignAndBigLocals(1); 872 break; 873 case 23: 874 TryAndGSCookieAndAlignAndBigLocals(1); 875 break; 876 case 24: 877 AllocaAndBigLocals(1); 878 break; 879 case 25: 880 TryAndAllocaAndBigLocals(1); 881 break; 882 case 26: 883 GSCookieAndAllocaAndBigLocals(1); 884 break; 885 case 27: 886 TryAndGSCookieAndAllocaAndBigLocals(1); 887 break; 888 case 28: 889 AlignAndAllocaAndBigLocals(1); 890 break; 891 case 29: 892 TryAndAlignAndAllocaAndBigLocals(1); 893 break; 894 case 30: 895 GSCookieAndAlignAndAllocaAndBigLocals(1); 896 break; 897 case 31: 898 TryAndGSCookieAndAlignAndAllocaAndBigLocals(1); 899 break; 900 case 32: 901 EbpAdj(1); 902 break; 903 case 33: 904 TryAndEbpAdj(1); 905 break; 906 case 34: 907 GSCookieAndEbpAdj(1); 908 break; 909 case 35: 910 TryAndGSCookieAndEbpAdj(1); 911 break; 912 case 36: 913 AlignAndEbpAdj(1); 914 break; 915 case 37: 916 TryAndAlignAndEbpAdj(1); 917 break; 918 case 38: 919 GSCookieAndAlignAndEbpAdj(1); 920 break; 921 case 39: 922 TryAndGSCookieAndAlignAndEbpAdj(1); 923 break; 924 case 40: 925 AllocaAndEbpAdj(1); 926 break; 927 case 41: 928 TryAndAllocaAndEbpAdj(1); 929 break; 930 case 42: 931 GSCookieAndAllocaAndEbpAdj(1); 932 break; 933 case 43: 934 TryAndGSCookieAndAllocaAndEbpAdj(1); 935 break; 936 case 44: 937 AlignAndAllocaAndEbpAdj(1); 938 break; 939 case 45: 940 TryAndAlignAndAllocaAndEbpAdj(1); 941 break; 942 case 46: 943 GSCookieAndAlignAndAllocaAndEbpAdj(1); 944 break; 945 case 47: 946 TryAndGSCookieAndAlignAndAllocaAndEbpAdj(1); 947 break; 948 } 949 } 950 __except(one) { caught = true; } 951 952 if (!caught) { 953 puts("ERROR - did not see expected exception"); 954 ++failures; 955 } 956 } 957 } 958 959 int main() { 960 __try { RunTests(); } 961 __except(1) { 962 puts("ERROR - Unexpectedly caught an exception"); 963 ++failures; 964 } 965 966 if (failures) { 967 printf("Test failed with %d failure%s\n", failures, 968 failures == 1 ? "" : "s"); 969 } else { 970 puts("Test passed"); 971 } 972 973 return failures; 974 } 975