xref: /llvm-project/clang/unittests/CodeGen/TBAAMetadataTest.cpp (revision 213aea4c5836934771eb97eb97e4c964053a8596)
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