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