1// 2// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5// 6 7#include "PreprocessorTest.h" 8#include "Token.h" 9 10class IfTest : public PreprocessorTest 11{ 12}; 13 14TEST_F(IfTest, If_0) 15{ 16 const char* str = "pass_1\n" 17 "#if 0\n" 18 "fail\n" 19 "#endif\n" 20 "pass_2\n"; 21 const char* expected = "pass_1\n" 22 "\n" 23 "\n" 24 "\n" 25 "pass_2\n"; 26 27 preprocess(str, expected); 28} 29 30TEST_F(IfTest, If_1) 31{ 32 const char* str = "pass_1\n" 33 "#if 1\n" 34 "pass_2\n" 35 "#endif\n" 36 "pass_3\n"; 37 const char* expected = "pass_1\n" 38 "\n" 39 "pass_2\n" 40 "\n" 41 "pass_3\n"; 42 43 preprocess(str, expected); 44} 45 46TEST_F(IfTest, If_0_Else) 47{ 48 const char* str = "pass_1\n" 49 "#if 0\n" 50 "fail\n" 51 "#else\n" 52 "pass_2\n" 53 "#endif\n" 54 "pass_3\n"; 55 const char* expected = "pass_1\n" 56 "\n" 57 "\n" 58 "\n" 59 "pass_2\n" 60 "\n" 61 "pass_3\n"; 62 63 preprocess(str, expected); 64} 65 66TEST_F(IfTest, If_1_Else) 67{ 68 const char* str = "pass_1\n" 69 "#if 1\n" 70 "pass_2\n" 71 "#else\n" 72 "fail\n" 73 "#endif\n" 74 "pass_3\n"; 75 const char* expected = "pass_1\n" 76 "\n" 77 "pass_2\n" 78 "\n" 79 "\n" 80 "\n" 81 "pass_3\n"; 82 83 preprocess(str, expected); 84} 85 86TEST_F(IfTest, If_0_Elif) 87{ 88 const char* str = "pass_1\n" 89 "#if 0\n" 90 "fail_1\n" 91 "#elif 0\n" 92 "fail_2\n" 93 "#elif 1\n" 94 "pass_2\n" 95 "#elif 1\n" 96 "fail_3\n" 97 "#else\n" 98 "fail_4\n" 99 "#endif\n" 100 "pass_3\n"; 101 const char* expected = "pass_1\n" 102 "\n" 103 "\n" 104 "\n" 105 "\n" 106 "\n" 107 "pass_2\n" 108 "\n" 109 "\n" 110 "\n" 111 "\n" 112 "\n" 113 "pass_3\n"; 114 115 preprocess(str, expected); 116} 117 118TEST_F(IfTest, If_1_Elif) 119{ 120 const char* str = "pass_1\n" 121 "#if 1\n" 122 "pass_2\n" 123 "#elif 0\n" 124 "fail_1\n" 125 "#elif 1\n" 126 "fail_2\n" 127 "#else\n" 128 "fail_4\n" 129 "#endif\n" 130 "pass_3\n"; 131 const char* expected = "pass_1\n" 132 "\n" 133 "pass_2\n" 134 "\n" 135 "\n" 136 "\n" 137 "\n" 138 "\n" 139 "\n" 140 "\n" 141 "pass_3\n"; 142 143 preprocess(str, expected); 144} 145 146TEST_F(IfTest, If_Elif_Else) 147{ 148 const char* str = "pass_1\n" 149 "#if 0\n" 150 "fail_1\n" 151 "#elif 0\n" 152 "fail_2\n" 153 "#elif 0\n" 154 "fail_3\n" 155 "#else\n" 156 "pass_2\n" 157 "#endif\n" 158 "pass_3\n"; 159 const char* expected = "pass_1\n" 160 "\n" 161 "\n" 162 "\n" 163 "\n" 164 "\n" 165 "\n" 166 "\n" 167 "pass_2\n" 168 "\n" 169 "pass_3\n"; 170 171 preprocess(str, expected); 172} 173 174TEST_F(IfTest, If_0_Nested) 175{ 176 const char* str = "pass_1\n" 177 "#if 0\n" 178 "fail_1\n" 179 "#if 1\n" 180 "fail_2\n" 181 "#else\n" 182 "fail_3\n" 183 "#endif\n" 184 "#else\n" 185 "pass_2\n" 186 "#endif\n" 187 "pass_3\n"; 188 const char* expected = "pass_1\n" 189 "\n" 190 "\n" 191 "\n" 192 "\n" 193 "\n" 194 "\n" 195 "\n" 196 "\n" 197 "pass_2\n" 198 "\n" 199 "pass_3\n"; 200 201 preprocess(str, expected); 202} 203 204TEST_F(IfTest, If_1_Nested) 205{ 206 const char* str = "pass_1\n" 207 "#if 1\n" 208 "pass_2\n" 209 "#if 1\n" 210 "pass_3\n" 211 "#else\n" 212 "fail_1\n" 213 "#endif\n" 214 "#else\n" 215 "fail_2\n" 216 "#endif\n" 217 "pass_4\n"; 218 const char* expected = "pass_1\n" 219 "\n" 220 "pass_2\n" 221 "\n" 222 "pass_3\n" 223 "\n" 224 "\n" 225 "\n" 226 "\n" 227 "\n" 228 "\n" 229 "pass_4\n"; 230 231 preprocess(str, expected); 232} 233 234TEST_F(IfTest, OperatorPrecedence) 235{ 236 const char* str = "#if 1 + 2 * 3 + - (26 % 17 - + 4 / 2)\n" 237 "fail_1\n" 238 "#else\n" 239 "pass_1\n" 240 "#endif\n"; 241 const char* expected = "\n" 242 "\n" 243 "\n" 244 "pass_1\n" 245 "\n"; 246 247 preprocess(str, expected); 248} 249 250TEST_F(IfTest, OperatorDefined) 251{ 252 const char* str = "#if defined foo\n" 253 "fail_1\n" 254 "#else\n" 255 "pass_1\n" 256 "#endif\n" 257 "#define foo\n" 258 "#if defined(foo)\n" 259 "pass_2\n" 260 "#else\n" 261 "fail_2\n" 262 "#endif\n" 263 "#undef foo\n" 264 "#if defined ( foo ) \n" 265 "fail_3\n" 266 "#else\n" 267 "pass_3\n" 268 "#endif\n"; 269 const char* expected = "\n" 270 "\n" 271 "\n" 272 "pass_1\n" 273 "\n" 274 "\n" 275 "\n" 276 "pass_2\n" 277 "\n" 278 "\n" 279 "\n" 280 "\n" 281 "\n" 282 "\n" 283 "\n" 284 "pass_3\n" 285 "\n"; 286 287 preprocess(str, expected); 288} 289 290TEST_F(IfTest, OperatorEQ) 291{ 292 const char* str = "#if 4 - 1 == 2 + 1\n" 293 "pass\n" 294 "#else\n" 295 "fail\n" 296 "#endif\n"; 297 const char* expected = "\n" 298 "pass\n" 299 "\n" 300 "\n" 301 "\n"; 302 303 preprocess(str, expected); 304} 305 306TEST_F(IfTest, OperatorNE) 307{ 308 const char* str = "#if 1 != 2\n" 309 "pass\n" 310 "#else\n" 311 "fail\n" 312 "#endif\n"; 313 const char* expected = "\n" 314 "pass\n" 315 "\n" 316 "\n" 317 "\n"; 318 319 preprocess(str, expected); 320} 321 322TEST_F(IfTest, OperatorLess) 323{ 324 const char* str = "#if 1 < 2\n" 325 "pass\n" 326 "#else\n" 327 "fail\n" 328 "#endif\n"; 329 const char* expected = "\n" 330 "pass\n" 331 "\n" 332 "\n" 333 "\n"; 334 335 preprocess(str, expected); 336} 337 338TEST_F(IfTest, OperatorGreater) 339{ 340 const char* str = "#if 2 > 1\n" 341 "pass\n" 342 "#else\n" 343 "fail\n" 344 "#endif\n"; 345 const char* expected = "\n" 346 "pass\n" 347 "\n" 348 "\n" 349 "\n"; 350 351 preprocess(str, expected); 352} 353 354TEST_F(IfTest, OperatorLE) 355{ 356 const char* str = "#if 1 <= 2\n" 357 "pass_1\n" 358 "#else\n" 359 "fail_1\n" 360 "#endif\n" 361 "#if 2 <= 2\n" 362 "pass_2\n" 363 "#else\n" 364 "fail_2\n" 365 "#endif\n"; 366 const char* expected = "\n" 367 "pass_1\n" 368 "\n" 369 "\n" 370 "\n" 371 "\n" 372 "pass_2\n" 373 "\n" 374 "\n" 375 "\n"; 376 377 preprocess(str, expected); 378} 379 380TEST_F(IfTest, OperatorGE) 381{ 382 const char* str = "#if 2 >= 1\n" 383 "pass_1\n" 384 "#else\n" 385 "fail_1\n" 386 "#endif\n" 387 "#if 2 >= 2\n" 388 "pass_2\n" 389 "#else\n" 390 "fail_2\n" 391 "#endif\n"; 392 const char* expected = "\n" 393 "pass_1\n" 394 "\n" 395 "\n" 396 "\n" 397 "\n" 398 "pass_2\n" 399 "\n" 400 "\n" 401 "\n"; 402 403 preprocess(str, expected); 404} 405 406TEST_F(IfTest, OperatorBitwiseOR) 407{ 408 const char* str = "#if (0xaaaaaaaa | 0x55555555) == 0xffffffff\n" 409 "pass\n" 410 "#else\n" 411 "fail\n" 412 "#endif\n"; 413 const char* expected = "\n" 414 "pass\n" 415 "\n" 416 "\n" 417 "\n"; 418 419 preprocess(str, expected); 420} 421 422TEST_F(IfTest, OperatorBitwiseAND) 423{ 424 const char* str = "#if (0xaaaaaaa & 0x5555555) == 0\n" 425 "pass\n" 426 "#else\n" 427 "fail\n" 428 "#endif\n"; 429 const char* expected = "\n" 430 "pass\n" 431 "\n" 432 "\n" 433 "\n"; 434 435 preprocess(str, expected); 436} 437 438TEST_F(IfTest, OperatorBitwiseXOR) 439{ 440 const char* str = "#if (0xaaaaaaa ^ 0x5555555) == 0xfffffff\n" 441 "pass\n" 442 "#else\n" 443 "fail\n" 444 "#endif\n"; 445 const char* expected = "\n" 446 "pass\n" 447 "\n" 448 "\n" 449 "\n"; 450 451 preprocess(str, expected); 452} 453 454TEST_F(IfTest, OperatorBitwiseComplement) 455{ 456 const char* str = "#if (~ 0xdeadbeef) == -3735928560\n" 457 "pass\n" 458 "#else\n" 459 "fail\n" 460 "#endif\n"; 461 const char* expected = "\n" 462 "pass\n" 463 "\n" 464 "\n" 465 "\n"; 466 467 preprocess(str, expected); 468} 469 470TEST_F(IfTest, OperatorLeft) 471{ 472 const char* str = "#if (1 << 12) == 4096\n" 473 "pass\n" 474 "#else\n" 475 "fail\n" 476 "#endif\n"; 477 const char* expected = "\n" 478 "pass\n" 479 "\n" 480 "\n" 481 "\n"; 482 483 preprocess(str, expected); 484} 485 486TEST_F(IfTest, OperatorRight) 487{ 488 const char* str = "#if (31762 >> 8) == 124\n" 489 "pass\n" 490 "#else\n" 491 "fail\n" 492 "#endif\n"; 493 const char* expected = "\n" 494 "pass\n" 495 "\n" 496 "\n" 497 "\n"; 498 499 preprocess(str, expected); 500} 501 502TEST_F(IfTest, ExpressionWithMacros) 503{ 504 const char* str = "#define one 1\n" 505 "#define two 2\n" 506 "#define three 3\n" 507 "#if one + two == three\n" 508 "pass\n" 509 "#else\n" 510 "fail\n" 511 "#endif\n"; 512 const char* expected = "\n" 513 "\n" 514 "\n" 515 "\n" 516 "pass\n" 517 "\n" 518 "\n" 519 "\n"; 520 521 preprocess(str, expected); 522} 523 524TEST_F(IfTest, JunkInsideExcludedBlockIgnored) 525{ 526 const char* str = "#if 0\n" 527 "foo !@#$%^&* .1bar\n" 528 "#foo\n" 529 "#if bar\n" 530 "fail\n" 531 "#endif\n" 532 "#else\n" 533 "pass\n" 534 "#endif\n"; 535 const char* expected = "\n" 536 "\n" 537 "\n" 538 "\n" 539 "\n" 540 "\n" 541 "\n" 542 "pass\n" 543 "\n"; 544 545 preprocess(str, expected); 546} 547 548TEST_F(IfTest, Ifdef) 549{ 550 const char* str = "#define foo\n" 551 "#ifdef foo\n" 552 "pass_1\n" 553 "#else\n" 554 "fail_1\n" 555 "#endif\n" 556 "#undef foo\n" 557 "#ifdef foo\n" 558 "fail_2\n" 559 "#else\n" 560 "pass_2\n" 561 "#endif\n"; 562 const char* expected = "\n" 563 "\n" 564 "pass_1\n" 565 "\n" 566 "\n" 567 "\n" 568 "\n" 569 "\n" 570 "\n" 571 "\n" 572 "pass_2\n" 573 "\n"; 574 575 preprocess(str, expected); 576} 577 578TEST_F(IfTest, Ifndef) 579{ 580 const char* str = "#define foo\n" 581 "#ifndef foo\n" 582 "fail_1\n" 583 "#else\n" 584 "pass_1\n" 585 "#endif\n" 586 "#undef foo\n" 587 "#ifndef foo\n" 588 "pass_2\n" 589 "#else\n" 590 "fail_2\n" 591 "#endif\n"; 592 const char* expected = "\n" 593 "\n" 594 "\n" 595 "\n" 596 "pass_1\n" 597 "\n" 598 "\n" 599 "\n" 600 "pass_2\n" 601 "\n" 602 "\n" 603 "\n"; 604 605 preprocess(str, expected); 606} 607 608TEST_F(IfTest, MissingExpression) 609{ 610 const char* str = "#if\n" 611 "#endif\n"; 612 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 613 614 EXPECT_CALL(mDiagnostics, 615 print(pp::Diagnostics::INVALID_EXPRESSION, 616 pp::SourceLocation(0, 1), 617 "syntax error")); 618 619 pp::Token token; 620 mPreprocessor.lex(&token); 621} 622 623TEST_F(IfTest, DivisionByZero) 624{ 625 const char* str = "#if 1 / (3 - (1 + 2))\n" 626 "#endif\n"; 627 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 628 629 EXPECT_CALL(mDiagnostics, 630 print(pp::Diagnostics::DIVISION_BY_ZERO, 631 pp::SourceLocation(0, 1), "1 / 0")); 632 633 pp::Token token; 634 mPreprocessor.lex(&token); 635} 636 637TEST_F(IfTest, ModuloByZero) 638{ 639 const char* str = "#if 1 % (3 - (1 + 2))\n" 640 "#endif\n"; 641 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 642 643 EXPECT_CALL(mDiagnostics, 644 print(pp::Diagnostics::DIVISION_BY_ZERO, 645 pp::SourceLocation(0, 1), "1 % 0")); 646 647 pp::Token token; 648 mPreprocessor.lex(&token); 649} 650 651TEST_F(IfTest, DecIntegerOverflow) 652{ 653 const char* str = "#if 4294967296\n" 654 "#endif\n"; 655 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 656 657 EXPECT_CALL(mDiagnostics, 658 print(pp::Diagnostics::INTEGER_OVERFLOW, 659 pp::SourceLocation(0, 1), "4294967296")); 660 661 pp::Token token; 662 mPreprocessor.lex(&token); 663} 664 665TEST_F(IfTest, OctIntegerOverflow) 666{ 667 const char* str = "#if 077777777777\n" 668 "#endif\n"; 669 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 670 671 EXPECT_CALL(mDiagnostics, 672 print(pp::Diagnostics::INTEGER_OVERFLOW, 673 pp::SourceLocation(0, 1), "077777777777")); 674 675 pp::Token token; 676 mPreprocessor.lex(&token); 677} 678 679TEST_F(IfTest, HexIntegerOverflow) 680{ 681 const char* str = "#if 0xfffffffff\n" 682 "#endif\n"; 683 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 684 685 EXPECT_CALL(mDiagnostics, 686 print(pp::Diagnostics::INTEGER_OVERFLOW, 687 pp::SourceLocation(0, 1), "0xfffffffff")); 688 689 pp::Token token; 690 mPreprocessor.lex(&token); 691} 692 693TEST_F(IfTest, UndefinedMacro) 694{ 695 const char* str = "#if UNDEFINED\n" 696 "#endif\n"; 697 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 698 699 EXPECT_CALL(mDiagnostics, 700 print(pp::Diagnostics::INVALID_EXPRESSION, 701 pp::SourceLocation(0, 1), 702 "syntax error")); 703 EXPECT_CALL(mDiagnostics, 704 print(pp::Diagnostics::CONDITIONAL_UNEXPECTED_TOKEN, 705 pp::SourceLocation(0, 1), 706 "UNDEFINED")); 707 708 pp::Token token; 709 mPreprocessor.lex(&token); 710} 711 712TEST_F(IfTest, InvalidExpressionIgnoredForExcludedElif) 713{ 714 const char* str = "#if 1\n" 715 "pass\n" 716 "#elif UNDEFINED\n" 717 "fail\n" 718 "#endif\n"; 719 const char* expected = "\n" 720 "pass\n" 721 "\n" 722 "\n" 723 "\n"; 724 725 // No error or warning. 726 using testing::_; 727 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0); 728 729 preprocess(str, expected); 730} 731 732TEST_F(IfTest, ElseWithoutIf) 733{ 734 const char* str = "#else\n"; 735 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 736 737 EXPECT_CALL(mDiagnostics, 738 print(pp::Diagnostics::CONDITIONAL_ELSE_WITHOUT_IF, 739 pp::SourceLocation(0, 1), 740 "else")); 741 742 pp::Token token; 743 mPreprocessor.lex(&token); 744} 745 746TEST_F(IfTest, ElifWithoutIf) 747{ 748 const char* str = "#elif 1\n"; 749 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 750 751 EXPECT_CALL(mDiagnostics, 752 print(pp::Diagnostics::CONDITIONAL_ELIF_WITHOUT_IF, 753 pp::SourceLocation(0, 1), 754 "elif")); 755 756 pp::Token token; 757 mPreprocessor.lex(&token); 758} 759 760TEST_F(IfTest, EndifWithoutIf) 761{ 762 const char* str = "#endif\n"; 763 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 764 765 EXPECT_CALL(mDiagnostics, 766 print(pp::Diagnostics::CONDITIONAL_ENDIF_WITHOUT_IF, 767 pp::SourceLocation(0, 1), 768 "endif")); 769 770 pp::Token token; 771 mPreprocessor.lex(&token); 772} 773 774TEST_F(IfTest, ElseAfterElse) 775{ 776 const char* str = "#if 1\n" 777 "#else\n" 778 "#else\n" 779 "#endif\n"; 780 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 781 782 EXPECT_CALL(mDiagnostics, 783 print(pp::Diagnostics::CONDITIONAL_ELSE_AFTER_ELSE, 784 pp::SourceLocation(0, 3), 785 "else")); 786 787 pp::Token token; 788 mPreprocessor.lex(&token); 789} 790 791TEST_F(IfTest, ElifAfterElse) 792{ 793 const char* str = "#if 1\n" 794 "#else\n" 795 "#elif 0\n" 796 "#endif\n"; 797 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 798 799 EXPECT_CALL(mDiagnostics, 800 print(pp::Diagnostics::CONDITIONAL_ELIF_AFTER_ELSE, 801 pp::SourceLocation(0, 3), 802 "elif")); 803 804 pp::Token token; 805 mPreprocessor.lex(&token); 806} 807 808TEST_F(IfTest, UnterminatedIf) 809{ 810 const char* str = "#if 1\n"; 811 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 812 813 EXPECT_CALL(mDiagnostics, 814 print(pp::Diagnostics::CONDITIONAL_UNTERMINATED, 815 pp::SourceLocation(0, 1), 816 "if")); 817 818 pp::Token token; 819 mPreprocessor.lex(&token); 820} 821 822TEST_F(IfTest, UnterminatedIfdef) 823{ 824 const char* str = "#ifdef foo\n"; 825 ASSERT_TRUE(mPreprocessor.init(1, &str, 0)); 826 827 EXPECT_CALL(mDiagnostics, 828 print(pp::Diagnostics::CONDITIONAL_UNTERMINATED, 829 pp::SourceLocation(0, 1), 830 "ifdef")); 831 832 pp::Token token; 833 mPreprocessor.lex(&token); 834} 835 836