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