1 //=== unittests/CodeGen/TBAAMetadataTest.cpp - Checks metadata generation -===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "IRMatchers.h" 10 #include "TestCompiler.h" 11 #include "clang/AST/ASTConsumer.h" 12 #include "clang/AST/ASTContext.h" 13 #include "clang/Basic/SourceManager.h" 14 #include "clang/Basic/TargetInfo.h" 15 #include "llvm/IR/Constants.h" 16 #include "llvm/Support/MemoryBuffer.h" 17 #include "gtest/gtest.h" 18 #include <memory> 19 20 using namespace llvm; 21 22 namespace { 23 24 struct TBAATestCompiler : public TestCompiler { 25 TBAATestCompiler(clang::LangOptions LO, clang::CodeGenOptions CGO) 26 : TestCompiler(LO, CGO) {} 27 static clang::CodeGenOptions getCommonCodeGenOpts() { 28 clang::CodeGenOptions CGOpts; 29 CGOpts.StructPathTBAA = 1; 30 CGOpts.OptimizationLevel = 1; 31 return CGOpts; 32 } 33 }; 34 35 auto OmnipotentCharC = MMTuple( 36 MMString("omnipotent char"), 37 MMTuple( 38 MMString("Simple C/C++ TBAA")), 39 MConstInt(0, 64) 40 ); 41 42 auto AnyPtr = MMTuple( 43 MMString("any pointer"), 44 OmnipotentCharC, 45 MConstInt(0, 64) 46 ); 47 48 auto OmnipotentCharCXX = MMTuple( 49 MMString("omnipotent char"), 50 MMTuple( 51 MMString("Simple C++ TBAA")), 52 MConstInt(0, 64) 53 ); 54 55 56 TEST(TBAAMetadataTest, BasicTypes) { 57 const char TestProgram[] = R"**( 58 void func(char *CP, short *SP, int *IP, long long *LP, void **VPP, 59 int **IPP) { 60 *CP = 4; 61 *SP = 11; 62 *IP = 601; 63 *LP = 604; 64 *VPP = CP; 65 *IPP = IP; 66 } 67 )**"; 68 69 clang::LangOptions LO; 70 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 71 Compiler.init(TestProgram); 72 const BasicBlock *BB = Compiler.compile(); 73 74 const Instruction *I = match(BB, 75 MInstruction(Instruction::Store, 76 MConstInt(4, 8), 77 MMTuple( 78 OmnipotentCharC, 79 MSameAs(0), 80 MConstInt(0)))); 81 ASSERT_TRUE(I); 82 83 I = matchNext(I, 84 MInstruction(Instruction::Store, 85 MConstInt(11, 16), 86 MMTuple( 87 MMTuple( 88 MMString("short"), 89 OmnipotentCharC, 90 MConstInt(0)), 91 MSameAs(0), 92 MConstInt(0)))); 93 ASSERT_TRUE(I); 94 95 I = matchNext(I, 96 MInstruction(Instruction::Store, 97 MConstInt(601, 32), 98 MMTuple( 99 MMTuple( 100 MMString("int"), 101 OmnipotentCharC, 102 MConstInt(0)), 103 MSameAs(0), 104 MConstInt(0)))); 105 ASSERT_TRUE(I); 106 107 I = matchNext(I, 108 MInstruction(Instruction::Store, 109 MConstInt(604, 64), 110 MMTuple( 111 MMTuple( 112 MMString("long long"), 113 OmnipotentCharC, 114 MConstInt(0)), 115 MSameAs(0), 116 MConstInt(0)))); 117 ASSERT_TRUE(I); 118 119 I = matchNext(I, 120 MInstruction(Instruction::Store, 121 MValType(PointerType::getUnqual(Compiler.Context)), 122 MMTuple( 123 MMTuple( 124 MMString("p1 void"), 125 AnyPtr, 126 MConstInt(0)), 127 MSameAs(0), 128 MConstInt(0)))); 129 ASSERT_TRUE(I); 130 131 I = matchNext(I, 132 MInstruction(Instruction::Store, 133 MValType(PointerType::getUnqual(Compiler.Context)), 134 MMTuple( 135 MMTuple( 136 MMString("p1 int"), 137 AnyPtr, 138 MConstInt(0)), 139 MSameAs(0), 140 MConstInt(0)))); 141 ASSERT_TRUE(I); 142 } 143 144 TEST(TBAAMetadataTest, CFields) { 145 const char TestProgram[] = R"**( 146 struct ABC { 147 short f16; 148 int f32; 149 long long f64; 150 unsigned short f16_2; 151 unsigned f32_2; 152 unsigned long long f64_2; 153 }; 154 155 void func(struct ABC *A) { 156 A->f32 = 4; 157 A->f16 = 11; 158 A->f64 = 601; 159 A->f16_2 = 22; 160 A->f32_2 = 77; 161 A->f64_2 = 604; 162 } 163 )**"; 164 165 clang::LangOptions LO; 166 LO.C11 = 1; 167 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 168 Compiler.init(TestProgram); 169 const BasicBlock *BB = Compiler.compile(); 170 171 auto StructABC = MMTuple( 172 MMString("ABC"), 173 MMTuple( 174 MMString("short"), 175 OmnipotentCharC, 176 MConstInt(0)), 177 MConstInt(0), 178 MMTuple( 179 MMString("int"), 180 OmnipotentCharC, 181 MConstInt(0)), 182 MConstInt(4), 183 MMTuple( 184 MMString("long long"), 185 OmnipotentCharC, 186 MConstInt(0)), 187 MConstInt(8), 188 MSameAs(1), 189 MConstInt(16), 190 MSameAs(3), 191 MConstInt(20), 192 MSameAs(5), 193 MConstInt(24)); 194 195 const Instruction *I = match(BB, 196 MInstruction(Instruction::Store, 197 MConstInt(4, 32), 198 MMTuple( 199 StructABC, 200 MMTuple( 201 MMString("int"), 202 OmnipotentCharC, 203 MConstInt(0)), 204 MConstInt(4)))); 205 ASSERT_TRUE(I); 206 207 I = matchNext(I, 208 MInstruction(Instruction::Store, 209 MConstInt(11, 16), 210 MMTuple( 211 StructABC, 212 MMTuple( 213 MMString("short"), 214 OmnipotentCharC, 215 MConstInt(0)), 216 MConstInt(0)))); 217 ASSERT_TRUE(I); 218 219 I = matchNext(I, 220 MInstruction(Instruction::Store, 221 MConstInt(601, 64), 222 MMTuple( 223 StructABC, 224 MMTuple( 225 MMString("long long"), 226 OmnipotentCharC, 227 MConstInt(0)), 228 MConstInt(8)))); 229 ASSERT_TRUE(I); 230 231 I = matchNext(I, 232 MInstruction(Instruction::Store, 233 MConstInt(22, 16), 234 MMTuple( 235 StructABC, 236 MMTuple( 237 MMString("short"), 238 OmnipotentCharC, 239 MConstInt(0)), 240 MConstInt(16)))); 241 ASSERT_TRUE(I); 242 243 I = matchNext(I, 244 MInstruction(Instruction::Store, 245 MConstInt(77, 32), 246 MMTuple( 247 StructABC, 248 MMTuple( 249 MMString("int"), 250 OmnipotentCharC, 251 MConstInt(0)), 252 MConstInt(20)))); 253 ASSERT_TRUE(I); 254 255 I = matchNext(I, 256 MInstruction(Instruction::Store, 257 MConstInt(604, 64), 258 MMTuple( 259 StructABC, 260 MMTuple( 261 MMString("long long"), 262 OmnipotentCharC, 263 MConstInt(0)), 264 MConstInt(24)))); 265 ASSERT_TRUE(I); 266 } 267 268 TEST(TBAAMetadataTest, CTypedefFields) { 269 const char TestProgram[] = R"**( 270 typedef struct { 271 short f16; 272 int f32; 273 } ABC; 274 typedef struct { 275 short value_f16; 276 int value_f32; 277 } CDE; 278 279 void func(ABC *A, CDE *B) { 280 A->f32 = 4; 281 A->f16 = 11; 282 B->value_f32 = 44; 283 B->value_f16 = 111; 284 } 285 )**"; 286 287 clang::LangOptions LO; 288 LO.C11 = 1; 289 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 290 Compiler.init(TestProgram); 291 const BasicBlock *BB = Compiler.compile(); 292 293 auto NamelessStruct = MMTuple( 294 MMString(""), 295 MMTuple( 296 MMString("short"), 297 OmnipotentCharC, 298 MConstInt(0)), 299 MConstInt(0), 300 MMTuple( 301 MMString("int"), 302 OmnipotentCharC, 303 MConstInt(0)), 304 MConstInt(4)); 305 306 const Metadata *MetaABC = nullptr; 307 const Instruction *I = match(BB, 308 MInstruction(Instruction::Store, 309 MConstInt(4, 32), 310 MMTuple( 311 MMSave(MetaABC, NamelessStruct), 312 MMTuple( 313 MMString("int"), 314 OmnipotentCharC, 315 MConstInt(0)), 316 MConstInt(4)))); 317 ASSERT_TRUE(I); 318 319 I = matchNext(I, 320 MInstruction(Instruction::Store, 321 MConstInt(11, 16), 322 MMTuple( 323 NamelessStruct, 324 MMTuple( 325 MMString("short"), 326 OmnipotentCharC, 327 MConstInt(0)), 328 MConstInt(0)))); 329 ASSERT_TRUE(I); 330 331 const Metadata *MetaCDE = nullptr; 332 I = matchNext(I, 333 MInstruction(Instruction::Store, 334 MConstInt(44, 32), 335 MMTuple( 336 MMSave(MetaCDE, NamelessStruct), 337 MMTuple( 338 MMString("int"), 339 OmnipotentCharC, 340 MConstInt(0)), 341 MConstInt(4)))); 342 ASSERT_TRUE(I); 343 344 I = matchNext(I, 345 MInstruction(Instruction::Store, 346 MConstInt(111, 16), 347 MMTuple( 348 NamelessStruct, 349 MMTuple( 350 MMString("short"), 351 OmnipotentCharC, 352 MConstInt(0)), 353 MConstInt(0)))); 354 ASSERT_TRUE(I); 355 356 // FIXME: Nameless structures used in definitions of 'ABC' and 'CDE' are 357 // different structures and must be described by different descriptors. 358 //ASSERT_TRUE(MetaABC != MetaCDE); 359 } 360 361 TEST(TBAAMetadataTest, CTypedefFields2) { 362 const char TestProgram[] = R"**( 363 typedef struct { 364 short f16; 365 int f32; 366 } ABC; 367 typedef struct { 368 short f16; 369 int f32; 370 } CDE; 371 372 void func(ABC *A, CDE *B) { 373 A->f32 = 4; 374 A->f16 = 11; 375 B->f32 = 44; 376 B->f16 = 111; 377 } 378 )**"; 379 380 clang::LangOptions LO; 381 LO.C11 = 1; 382 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 383 Compiler.init(TestProgram); 384 const BasicBlock *BB = Compiler.compile(); 385 386 auto NamelessStruct = MMTuple( 387 MMString(""), 388 MMTuple( 389 MMString("short"), 390 OmnipotentCharC, 391 MConstInt(0)), 392 MConstInt(0), 393 MMTuple( 394 MMString("int"), 395 OmnipotentCharC, 396 MConstInt(0)), 397 MConstInt(4)); 398 399 const Metadata *MetaABC = nullptr; 400 const Instruction *I = match(BB, 401 MInstruction(Instruction::Store, 402 MConstInt(4, 32), 403 MMTuple( 404 MMSave(MetaABC, NamelessStruct), 405 MMTuple( 406 MMString("int"), 407 OmnipotentCharC, 408 MConstInt(0)), 409 MConstInt(4)))); 410 ASSERT_TRUE(I); 411 412 I = matchNext(I, 413 MInstruction(Instruction::Store, 414 MConstInt(11, 16), 415 MMTuple( 416 NamelessStruct, 417 MMTuple( 418 MMString("short"), 419 OmnipotentCharC, 420 MConstInt(0)), 421 MConstInt(0)))); 422 ASSERT_TRUE(I); 423 424 const Metadata *MetaCDE = nullptr; 425 I = matchNext(I, 426 MInstruction(Instruction::Store, 427 MConstInt(44, 32), 428 MMTuple( 429 MMSave(MetaCDE, NamelessStruct), 430 MMTuple( 431 MMString("int"), 432 OmnipotentCharC, 433 MConstInt(0)), 434 MConstInt(4)))); 435 ASSERT_TRUE(I); 436 437 I = matchNext(I, 438 MInstruction(Instruction::Store, 439 MConstInt(111, 16), 440 MMTuple( 441 NamelessStruct, 442 MMTuple( 443 MMString("short"), 444 OmnipotentCharC, 445 MConstInt(0)), 446 MConstInt(0)))); 447 ASSERT_TRUE(I); 448 449 // FIXME: Nameless structures used in definitions of 'ABC' and 'CDE' are 450 // different structures, although they have the same field sequence. They must 451 // be described by different descriptors. 452 //ASSERT_TRUE(MetaABC != MetaCDE); 453 } 454 455 TEST(TBAAMetadataTest, CTypedefFields3) { 456 const char TestProgram[] = R"**( 457 typedef struct { 458 short f16; 459 int f32; 460 } ABC; 461 typedef struct { 462 int f32; 463 short f16; 464 } CDE; 465 466 void func(ABC *A, CDE *B) { 467 A->f32 = 4; 468 A->f16 = 11; 469 B->f32 = 44; 470 B->f16 = 111; 471 } 472 )**"; 473 474 clang::LangOptions LO; 475 LO.C11 = 1; 476 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 477 Compiler.init(TestProgram); 478 const BasicBlock *BB = Compiler.compile(); 479 480 auto NamelessStruct1 = MMTuple( 481 MMString(""), 482 MMTuple( 483 MMString("short"), 484 OmnipotentCharC, 485 MConstInt(0)), 486 MConstInt(0), 487 MMTuple( 488 MMString("int"), 489 OmnipotentCharC, 490 MConstInt(0)), 491 MConstInt(4)); 492 493 auto NamelessStruct2 = MMTuple( 494 MMString(""), 495 MMTuple( 496 MMString("int"), 497 OmnipotentCharC, 498 MConstInt(0)), 499 MConstInt(0), 500 MMTuple( 501 MMString("short"), 502 OmnipotentCharC, 503 MConstInt(0)), 504 MConstInt(4)); 505 506 const Instruction *I = match(BB, 507 MInstruction(Instruction::Store, 508 MConstInt(4, 32), 509 MMTuple( 510 NamelessStruct1, 511 MMTuple( 512 MMString("int"), 513 OmnipotentCharC, 514 MConstInt(0)), 515 MConstInt(4)))); 516 ASSERT_TRUE(I); 517 518 I = matchNext(I, 519 MInstruction(Instruction::Store, 520 MConstInt(11, 16), 521 MMTuple( 522 NamelessStruct1, 523 MMTuple( 524 MMString("short"), 525 OmnipotentCharC, 526 MConstInt(0)), 527 MConstInt(0)))); 528 ASSERT_TRUE(I); 529 530 I = matchNext(I, 531 MInstruction(Instruction::Store, 532 MConstInt(44, 32), 533 MMTuple( 534 NamelessStruct2, 535 MMTuple( 536 MMString("int"), 537 OmnipotentCharC, 538 MConstInt(0)), 539 MConstInt(0)))); 540 ASSERT_TRUE(I); 541 542 I = matchNext(I, 543 MInstruction(Instruction::Store, 544 MConstInt(111, 16), 545 MMTuple( 546 NamelessStruct2, 547 MMTuple( 548 MMString("short"), 549 OmnipotentCharC, 550 MConstInt(0)), 551 MConstInt(4)))); 552 ASSERT_TRUE(I); 553 } 554 555 TEST(TBAAMetadataTest, CXXFields) { 556 const char TestProgram[] = R"**( 557 struct ABC { 558 short f16; 559 int f32; 560 long long f64; 561 unsigned short f16_2; 562 unsigned f32_2; 563 unsigned long long f64_2; 564 }; 565 566 void func(struct ABC *A) { 567 A->f32 = 4; 568 A->f16 = 11; 569 A->f64 = 601; 570 A->f16_2 = 22; 571 A->f32_2 = 77; 572 A->f64_2 = 604; 573 } 574 )**"; 575 576 clang::LangOptions LO; 577 LO.CPlusPlus = 1; 578 LO.CPlusPlus11 = 1; 579 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 580 Compiler.init(TestProgram); 581 const BasicBlock *BB = Compiler.compile(); 582 583 auto StructABC = MMTuple( 584 MMString("_ZTS3ABC"), 585 MMTuple( 586 MMString("short"), 587 OmnipotentCharCXX, 588 MConstInt(0)), 589 MConstInt(0), 590 MMTuple( 591 MMString("int"), 592 OmnipotentCharCXX, 593 MConstInt(0)), 594 MConstInt(4), 595 MMTuple( 596 MMString("long long"), 597 OmnipotentCharCXX, 598 MConstInt(0)), 599 MConstInt(8), 600 MSameAs(1), 601 MConstInt(16), 602 MSameAs(3), 603 MConstInt(20), 604 MSameAs(5), 605 MConstInt(24)); 606 607 const Instruction *I = match(BB, 608 MInstruction(Instruction::Store, 609 MConstInt(4, 32), 610 MMTuple( 611 StructABC, 612 MMTuple( 613 MMString("int"), 614 OmnipotentCharCXX, 615 MConstInt(0)), 616 MConstInt(4)))); 617 ASSERT_TRUE(I); 618 619 I = matchNext(I, 620 MInstruction(Instruction::Store, 621 MConstInt(11, 16), 622 MMTuple( 623 StructABC, 624 MMTuple( 625 MMString("short"), 626 OmnipotentCharCXX, 627 MConstInt(0)), 628 MConstInt(0)))); 629 ASSERT_TRUE(I); 630 631 I = matchNext(I, 632 MInstruction(Instruction::Store, 633 MConstInt(601, 64), 634 MMTuple( 635 StructABC, 636 MMTuple( 637 MMString("long long"), 638 OmnipotentCharCXX, 639 MConstInt(0)), 640 MConstInt(8)))); 641 ASSERT_TRUE(I); 642 643 I = matchNext(I, 644 MInstruction(Instruction::Store, 645 MConstInt(22, 16), 646 MMTuple( 647 StructABC, 648 MMTuple( 649 MMString("short"), 650 OmnipotentCharCXX, 651 MConstInt(0)), 652 MConstInt(16)))); 653 ASSERT_TRUE(I); 654 655 I = matchNext(I, 656 MInstruction(Instruction::Store, 657 MConstInt(77, 32), 658 MMTuple( 659 StructABC, 660 MMTuple( 661 MMString("int"), 662 OmnipotentCharCXX, 663 MConstInt(0)), 664 MConstInt(20)))); 665 ASSERT_TRUE(I); 666 667 I = matchNext(I, 668 MInstruction(Instruction::Store, 669 MConstInt(604, 64), 670 MMTuple( 671 StructABC, 672 MMTuple( 673 MMString("long long"), 674 OmnipotentCharCXX, 675 MConstInt(0)), 676 MConstInt(24)))); 677 ASSERT_TRUE(I); 678 } 679 680 TEST(TBAAMetadataTest, CXXTypedefFields) { 681 const char TestProgram[] = R"**( 682 typedef struct { 683 short f16; 684 int f32; 685 } ABC; 686 typedef struct { 687 short value_f16; 688 int value_f32; 689 } CDE; 690 691 void func(ABC *A, CDE *B) { 692 A->f32 = 4; 693 A->f16 = 11; 694 B->value_f32 = 44; 695 B->value_f16 = 111; 696 } 697 )**"; 698 699 clang::LangOptions LO; 700 LO.CPlusPlus = 1; 701 LO.CPlusPlus11 = 1; 702 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 703 Compiler.init(TestProgram); 704 const BasicBlock *BB = Compiler.compile(); 705 706 auto StructABC = MMTuple( 707 MMString("_ZTS3ABC"), 708 MMTuple( 709 MMString("short"), 710 OmnipotentCharCXX, 711 MConstInt(0)), 712 MConstInt(0), 713 MMTuple( 714 MMString("int"), 715 OmnipotentCharCXX, 716 MConstInt(0)), 717 MConstInt(4)); 718 719 auto StructCDE = MMTuple( 720 MMString("_ZTS3CDE"), 721 MMTuple( 722 MMString("short"), 723 OmnipotentCharCXX, 724 MConstInt(0)), 725 MConstInt(0), 726 MMTuple( 727 MMString("int"), 728 OmnipotentCharCXX, 729 MConstInt(0)), 730 MConstInt(4)); 731 732 const Instruction *I = match(BB, 733 MInstruction(Instruction::Store, 734 MConstInt(4, 32), 735 MMTuple( 736 StructABC, 737 MMTuple( 738 MMString("int"), 739 OmnipotentCharCXX, 740 MConstInt(0)), 741 MConstInt(4)))); 742 ASSERT_TRUE(I); 743 744 I = matchNext(I, 745 MInstruction(Instruction::Store, 746 MConstInt(11, 16), 747 MMTuple( 748 StructABC, 749 MMTuple( 750 MMString("short"), 751 OmnipotentCharCXX, 752 MConstInt(0)), 753 MConstInt(0)))); 754 ASSERT_TRUE(I); 755 756 I = matchNext(I, 757 MInstruction(Instruction::Store, 758 MConstInt(44, 32), 759 MMTuple( 760 StructCDE, 761 MMTuple( 762 MMString("int"), 763 OmnipotentCharCXX, 764 MConstInt(0)), 765 MConstInt(4)))); 766 ASSERT_TRUE(I); 767 768 I = matchNext(I, 769 MInstruction(Instruction::Store, 770 MConstInt(111, 16), 771 MMTuple( 772 StructCDE, 773 MMTuple( 774 MMString("short"), 775 OmnipotentCharCXX, 776 MConstInt(0)), 777 MConstInt(0)))); 778 ASSERT_TRUE(I); 779 } 780 781 TEST(TBAAMetadataTest, StructureFields) { 782 const char TestProgram[] = R"**( 783 struct Inner { 784 int f32; 785 }; 786 787 struct Outer { 788 short f16; 789 Inner b1; 790 Inner b2; 791 }; 792 793 void func(Outer *S) { 794 S->f16 = 14; 795 S->b1.f32 = 35; 796 S->b2.f32 = 77; 797 } 798 )**"; 799 800 clang::LangOptions LO; 801 LO.CPlusPlus = 1; 802 LO.CPlusPlus11 = 1; 803 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 804 Compiler.init(TestProgram); 805 const BasicBlock *BB = Compiler.compile(); 806 807 auto StructInner = MMTuple( 808 MMString("_ZTS5Inner"), 809 MMTuple( 810 MMString("int"), 811 OmnipotentCharCXX, 812 MConstInt(0)), 813 MConstInt(0)); 814 815 auto StructOuter = MMTuple( 816 MMString("_ZTS5Outer"), 817 MMTuple( 818 MMString("short"), 819 OmnipotentCharCXX, 820 MConstInt(0)), 821 MConstInt(0), 822 StructInner, 823 MConstInt(4), 824 MSameAs(3), 825 MConstInt(8)); 826 827 const Instruction *I = match(BB, 828 MInstruction(Instruction::Store, 829 MConstInt(14, 16), 830 MMTuple( 831 StructOuter, 832 MMTuple( 833 MMString("short"), 834 OmnipotentCharCXX, 835 MConstInt(0)), 836 MConstInt(0)))); 837 ASSERT_TRUE(I); 838 839 I = matchNext(I, 840 MInstruction(Instruction::Store, 841 MConstInt(35, 32), 842 MMTuple( 843 StructOuter, 844 MMTuple( 845 MMString("int"), 846 OmnipotentCharCXX, 847 MConstInt(0)), 848 MConstInt(4)))); 849 ASSERT_TRUE(I); 850 851 I = matchNext(I, 852 MInstruction(Instruction::Store, 853 MConstInt(77, 32), 854 MMTuple( 855 StructOuter, 856 MMTuple( 857 MMString("int"), 858 OmnipotentCharCXX, 859 MConstInt(0)), 860 MConstInt(8)))); 861 ASSERT_TRUE(I); 862 } 863 864 TEST(TBAAMetadataTest, ArrayFields) { 865 const char TestProgram[] = R"**( 866 struct Inner { 867 int f32; 868 }; 869 870 struct Outer { 871 short f16; 872 Inner b1[2]; 873 }; 874 875 void func(Outer *S) { 876 S->f16 = 14; 877 S->b1[0].f32 = 35; 878 S->b1[1].f32 = 77; 879 } 880 )**"; 881 882 clang::LangOptions LO; 883 LO.CPlusPlus = 1; 884 LO.CPlusPlus11 = 1; 885 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 886 Compiler.init(TestProgram); 887 const BasicBlock *BB = Compiler.compile(); 888 889 auto StructInner = MMTuple( 890 MMString("_ZTS5Inner"), 891 MMTuple( 892 MMString("int"), 893 OmnipotentCharCXX, 894 MConstInt(0)), 895 MConstInt(0)); 896 897 auto StructOuter = MMTuple( 898 MMString("_ZTS5Outer"), 899 MMTuple( 900 MMString("short"), 901 OmnipotentCharCXX, 902 MConstInt(0)), 903 MConstInt(0), 904 OmnipotentCharCXX, // FIXME: Info about array field is lost. 905 MConstInt(4)); 906 907 const Instruction *I = match(BB, 908 MInstruction(Instruction::Store, 909 MConstInt(14, 16), 910 MMTuple( 911 StructOuter, 912 MMTuple( 913 MMString("short"), 914 OmnipotentCharCXX, 915 MConstInt(0)), 916 MConstInt(0)))); 917 ASSERT_TRUE(I); 918 919 I = matchNext(I, 920 MInstruction(Instruction::Store, 921 MConstInt(35, 32), 922 MMTuple( 923 StructInner, 924 MMTuple( 925 MMString("int"), 926 OmnipotentCharCXX, 927 MConstInt(0)), 928 MConstInt(0)))); 929 ASSERT_TRUE(I); 930 931 I = matchNext(I, 932 MInstruction(Instruction::Store, 933 MConstInt(77, 32), 934 MMTuple( 935 StructInner, 936 MMTuple( 937 MMString("int"), 938 OmnipotentCharCXX, 939 MConstInt(0)), 940 MConstInt(0)))); 941 ASSERT_TRUE(I); 942 } 943 944 TEST(TBAAMetadataTest, BaseClass) { 945 const char TestProgram[] = R"**( 946 struct Base { 947 int f32; 948 }; 949 950 struct Derived : public Base { 951 short f16; 952 }; 953 954 void func(Base *B, Derived *D) { 955 B->f32 = 14; 956 D->f16 = 35; 957 D->f32 = 77; 958 } 959 )**"; 960 961 clang::LangOptions LO; 962 LO.CPlusPlus = 1; 963 LO.CPlusPlus11 = 1; 964 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 965 Compiler.init(TestProgram); 966 const BasicBlock *BB = Compiler.compile(); 967 968 auto ClassBase = MMTuple( 969 MMString("_ZTS4Base"), 970 MMTuple( 971 MMString("int"), 972 OmnipotentCharCXX, 973 MConstInt(0)), 974 MConstInt(0)); 975 976 auto ClassDerived = 977 MMTuple(MMString("_ZTS7Derived"), ClassBase, MConstInt(0), 978 MMTuple(MMString("short"), OmnipotentCharCXX, MConstInt(0)), 979 MConstInt(4)); 980 981 const Instruction *I = match(BB, 982 MInstruction(Instruction::Store, 983 MConstInt(14, 32), 984 MMTuple( 985 ClassBase, 986 MMTuple( 987 MMString("int"), 988 OmnipotentCharCXX, 989 MConstInt(0)), 990 MConstInt(0)))); 991 ASSERT_TRUE(I); 992 993 I = matchNext(I, 994 MInstruction(Instruction::Store, 995 MConstInt(35, 16), 996 MMTuple( 997 ClassDerived, 998 MMTuple( 999 MMString("short"), 1000 OmnipotentCharCXX, 1001 MConstInt(0)), 1002 MConstInt(4)))); 1003 ASSERT_TRUE(I); 1004 1005 I = matchNext(I, 1006 MInstruction(Instruction::Store, 1007 MConstInt(77, 32), 1008 MMTuple( 1009 ClassBase, 1010 MMTuple( 1011 MMString("int"), 1012 OmnipotentCharCXX, 1013 MConstInt(0)), 1014 MConstInt(0)))); 1015 ASSERT_TRUE(I); 1016 } 1017 1018 TEST(TBAAMetadataTest, PolymorphicClass) { 1019 const char TestProgram[] = R"**( 1020 struct Base { 1021 virtual void m1(int *) = 0; 1022 int f32; 1023 }; 1024 1025 struct Derived : public Base { 1026 virtual void m1(int *) override; 1027 short f16; 1028 }; 1029 1030 void func(Base *B, Derived *D) { 1031 B->f32 = 14; 1032 D->f16 = 35; 1033 D->f32 = 77; 1034 } 1035 )**"; 1036 1037 clang::LangOptions LO; 1038 LO.CPlusPlus = 1; 1039 LO.CPlusPlus11 = 1; 1040 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 1041 Compiler.init(TestProgram); 1042 const BasicBlock *BB = Compiler.compile(); 1043 1044 auto ClassBase = MMTuple( 1045 MMString("_ZTS4Base"), 1046 MMTuple( 1047 MMString("int"), 1048 OmnipotentCharCXX, 1049 MConstInt(0)), 1050 MConstInt(Compiler.PtrSize)); 1051 1052 auto ClassDerived = 1053 MMTuple(MMString("_ZTS7Derived"), ClassBase, MConstInt(0), 1054 MMTuple(MMString("short"), OmnipotentCharCXX, MConstInt(0)), 1055 MConstInt(Compiler.PtrSize + 4)); 1056 1057 const Instruction *I = match(BB, 1058 MInstruction(Instruction::Store, 1059 MConstInt(14, 32), 1060 MMTuple( 1061 ClassBase, 1062 MMTuple( 1063 MMString("int"), 1064 OmnipotentCharCXX, 1065 MConstInt(0)), 1066 MConstInt(Compiler.PtrSize)))); 1067 ASSERT_TRUE(I); 1068 1069 I = matchNext(I, 1070 MInstruction(Instruction::Store, 1071 MConstInt(35, 16), 1072 MMTuple( 1073 ClassDerived, 1074 MMTuple( 1075 MMString("short"), 1076 OmnipotentCharCXX, 1077 MConstInt(0)), 1078 MConstInt(Compiler.PtrSize + 4)))); 1079 ASSERT_TRUE(I); 1080 1081 I = matchNext(I, 1082 MInstruction(Instruction::Store, 1083 MConstInt(77, 32), 1084 MMTuple( 1085 ClassBase, 1086 MMTuple( 1087 MMString("int"), 1088 OmnipotentCharCXX, 1089 MConstInt(0)), 1090 MConstInt(Compiler.PtrSize)))); 1091 ASSERT_TRUE(I); 1092 } 1093 1094 TEST(TBAAMetadataTest, VirtualBase) { 1095 const char TestProgram[] = R"**( 1096 struct Base { 1097 int f32; 1098 }; 1099 1100 struct Derived : public virtual Base { 1101 short f16; 1102 }; 1103 1104 void func(Base *B, Derived *D) { 1105 B->f32 = 14; 1106 D->f16 = 35; 1107 D->f32 = 77; 1108 } 1109 )**"; 1110 1111 clang::LangOptions LO; 1112 LO.CPlusPlus = 1; 1113 LO.CPlusPlus11 = 1; 1114 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 1115 Compiler.init(TestProgram); 1116 const BasicBlock *BB = Compiler.compile(); 1117 1118 auto ClassBase = MMTuple( 1119 MMString("_ZTS4Base"), 1120 MMTuple( 1121 MMString("int"), 1122 OmnipotentCharCXX, 1123 MConstInt(0)), 1124 MConstInt(0)); 1125 1126 auto ClassDerived = MMTuple( 1127 MMString("_ZTS7Derived"), 1128 MMTuple( 1129 MMString("short"), 1130 OmnipotentCharCXX, 1131 MConstInt(0)), 1132 MConstInt(Compiler.PtrSize)); 1133 1134 const Instruction *I = match(BB, 1135 MInstruction(Instruction::Store, 1136 MConstInt(14, 32), 1137 MMTuple( 1138 ClassBase, 1139 MMTuple( 1140 MMString("int"), 1141 OmnipotentCharCXX, 1142 MConstInt(0)), 1143 MConstInt(0)))); 1144 ASSERT_TRUE(I); 1145 1146 I = matchNext(I, 1147 MInstruction(Instruction::Store, 1148 MConstInt(35, 16), 1149 MMTuple( 1150 ClassDerived, 1151 MMTuple( 1152 MMString("short"), 1153 OmnipotentCharCXX, 1154 MConstInt(0)), 1155 MConstInt(Compiler.PtrSize)))); 1156 ASSERT_TRUE(I); 1157 1158 I = matchNext(I, 1159 MInstruction(Instruction::Load, 1160 MMTuple( 1161 MMTuple( 1162 MMString("vtable pointer"), 1163 MMTuple( 1164 MMString("Simple C++ TBAA")), 1165 MConstInt(0)), 1166 MSameAs(0), 1167 MConstInt(0)))); 1168 ASSERT_TRUE(I); 1169 1170 I = matchNext(I, 1171 MInstruction(Instruction::Store, 1172 MConstInt(77, 32), 1173 MMTuple( 1174 ClassBase, 1175 MMTuple( 1176 MMString("int"), 1177 OmnipotentCharCXX, 1178 MConstInt(0)), 1179 MConstInt(0)))); 1180 ASSERT_TRUE(I); 1181 } 1182 1183 TEST(TBAAMetadataTest, TemplSpec) { 1184 const char TestProgram[] = R"**( 1185 template<typename T1, typename T2> 1186 struct ABC { 1187 T1 f1; 1188 T2 f2; 1189 }; 1190 1191 void func(ABC<double, int> *p) { 1192 p->f1 = 12.1; 1193 p->f2 = 44; 1194 } 1195 )**"; 1196 1197 clang::LangOptions LO; 1198 LO.CPlusPlus = 1; 1199 LO.CPlusPlus11 = 1; 1200 TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts()); 1201 Compiler.init(TestProgram); 1202 const BasicBlock *BB = Compiler.compile(); 1203 1204 auto SpecABC = MMTuple( 1205 MMString("_ZTS3ABCIdiE"), 1206 MMTuple( 1207 MMString("double"), 1208 OmnipotentCharCXX, 1209 MConstInt(0)), 1210 MConstInt(0), 1211 MMTuple( 1212 MMString("int"), 1213 OmnipotentCharCXX, 1214 MConstInt(0)), 1215 MConstInt(8)); 1216 1217 const Instruction *I = match(BB, 1218 MInstruction(Instruction::Store, 1219 MValType(MType([](const Type &T)->bool { return T.isDoubleTy(); })), 1220 MMTuple( 1221 SpecABC, 1222 MMTuple( 1223 MMString("double"), 1224 OmnipotentCharCXX, 1225 MConstInt(0)), 1226 MConstInt(0)))); 1227 ASSERT_TRUE(I); 1228 1229 I = matchNext(I, 1230 MInstruction(Instruction::Store, 1231 MConstInt(44, 32), 1232 MMTuple( 1233 SpecABC, 1234 MMTuple( 1235 MMString("int"), 1236 OmnipotentCharCXX, 1237 MConstInt(0)), 1238 MConstInt(8)))); 1239 ASSERT_TRUE(I); 1240 } 1241 } 1242