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