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