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