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