xref: /llvm-project/clang/unittests/CodeGen/TBAAMetadataTest.cpp (revision 5b3247bf9f715cc1b399af1e17540b3a3ce9cdec)
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 {
25   TBAATestCompiler(clang::LangOptions LO, clang::CodeGenOptions CGO)
26     : TestCompiler(LO, CGO) {}
27   static clang::CodeGenOptions getCommonCodeGenOpts() {
28     clang::CodeGenOptions CGOpts;
29     CGOpts.StructPathTBAA = 1;
30     CGOpts.OptimizationLevel = 1;
31     return CGOpts;
32   }
33 };
34 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 =
972       MMTuple(MMString("_ZTS7Derived"), ClassBase, MConstInt(0),
973               MMTuple(MMString("short"), OmnipotentCharCXX, MConstInt(0)),
974               MConstInt(4));
975 
976   const Instruction *I = match(BB,
977       MInstruction(Instruction::Store,
978         MConstInt(14, 32),
979         MMTuple(
980           ClassBase,
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(35, 16),
991         MMTuple(
992           ClassDerived,
993           MMTuple(
994             MMString("short"),
995             OmnipotentCharCXX,
996             MConstInt(0)),
997           MConstInt(4))));
998   ASSERT_TRUE(I);
999 
1000   I = matchNext(I,
1001       MInstruction(Instruction::Store,
1002         MConstInt(77, 32),
1003         MMTuple(
1004           ClassBase,
1005           MMTuple(
1006             MMString("int"),
1007             OmnipotentCharCXX,
1008             MConstInt(0)),
1009           MConstInt(0))));
1010   ASSERT_TRUE(I);
1011 }
1012 
1013 TEST(TBAAMetadataTest, PolymorphicClass) {
1014   const char TestProgram[] = R"**(
1015     struct Base {
1016       virtual void m1(int *) = 0;
1017       int f32;
1018     };
1019 
1020     struct Derived : public Base {
1021       virtual void m1(int *) override;
1022       short f16;
1023     };
1024 
1025     void func(Base *B, Derived *D) {
1026       B->f32 = 14;
1027       D->f16 = 35;
1028       D->f32 = 77;
1029     }
1030   )**";
1031 
1032   clang::LangOptions LO;
1033   LO.CPlusPlus = 1;
1034   LO.CPlusPlus11 = 1;
1035   TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
1036   Compiler.init(TestProgram);
1037   const BasicBlock *BB = Compiler.compile();
1038 
1039   auto ClassBase = MMTuple(
1040     MMString("_ZTS4Base"),
1041     MMTuple(
1042       MMString("int"),
1043       OmnipotentCharCXX,
1044       MConstInt(0)),
1045     MConstInt(Compiler.PtrSize));
1046 
1047   auto ClassDerived =
1048       MMTuple(MMString("_ZTS7Derived"), ClassBase, MConstInt(0),
1049               MMTuple(MMString("short"), OmnipotentCharCXX, MConstInt(0)),
1050               MConstInt(Compiler.PtrSize + 4));
1051 
1052   const Instruction *I = match(BB,
1053       MInstruction(Instruction::Store,
1054         MConstInt(14, 32),
1055         MMTuple(
1056           ClassBase,
1057           MMTuple(
1058             MMString("int"),
1059             OmnipotentCharCXX,
1060             MConstInt(0)),
1061           MConstInt(Compiler.PtrSize))));
1062   ASSERT_TRUE(I);
1063 
1064   I = matchNext(I,
1065       MInstruction(Instruction::Store,
1066         MConstInt(35, 16),
1067         MMTuple(
1068           ClassDerived,
1069           MMTuple(
1070             MMString("short"),
1071             OmnipotentCharCXX,
1072             MConstInt(0)),
1073           MConstInt(Compiler.PtrSize + 4))));
1074   ASSERT_TRUE(I);
1075 
1076   I = matchNext(I,
1077       MInstruction(Instruction::Store,
1078         MConstInt(77, 32),
1079         MMTuple(
1080           ClassBase,
1081           MMTuple(
1082             MMString("int"),
1083             OmnipotentCharCXX,
1084             MConstInt(0)),
1085           MConstInt(Compiler.PtrSize))));
1086   ASSERT_TRUE(I);
1087 }
1088 
1089 TEST(TBAAMetadataTest, VirtualBase) {
1090   const char TestProgram[] = R"**(
1091     struct Base {
1092       int f32;
1093     };
1094 
1095     struct Derived : public virtual Base {
1096       short f16;
1097     };
1098 
1099     void func(Base *B, Derived *D) {
1100       B->f32 = 14;
1101       D->f16 = 35;
1102       D->f32 = 77;
1103     }
1104   )**";
1105 
1106   clang::LangOptions LO;
1107   LO.CPlusPlus = 1;
1108   LO.CPlusPlus11 = 1;
1109   TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
1110   Compiler.init(TestProgram);
1111   const BasicBlock *BB = Compiler.compile();
1112 
1113   auto ClassBase = MMTuple(
1114     MMString("_ZTS4Base"),
1115     MMTuple(
1116       MMString("int"),
1117       OmnipotentCharCXX,
1118       MConstInt(0)),
1119     MConstInt(0));
1120 
1121   auto ClassDerived = MMTuple(
1122     MMString("_ZTS7Derived"),
1123     MMTuple(
1124       MMString("short"),
1125       OmnipotentCharCXX,
1126       MConstInt(0)),
1127     MConstInt(Compiler.PtrSize));
1128 
1129   const Instruction *I = match(BB,
1130       MInstruction(Instruction::Store,
1131         MConstInt(14, 32),
1132         MMTuple(
1133           ClassBase,
1134           MMTuple(
1135             MMString("int"),
1136             OmnipotentCharCXX,
1137             MConstInt(0)),
1138           MConstInt(0))));
1139   ASSERT_TRUE(I);
1140 
1141   I = matchNext(I,
1142       MInstruction(Instruction::Store,
1143         MConstInt(35, 16),
1144         MMTuple(
1145           ClassDerived,
1146           MMTuple(
1147             MMString("short"),
1148             OmnipotentCharCXX,
1149             MConstInt(0)),
1150           MConstInt(Compiler.PtrSize))));
1151   ASSERT_TRUE(I);
1152 
1153   I = matchNext(I,
1154       MInstruction(Instruction::Load,
1155         MMTuple(
1156           MMTuple(
1157             MMString("vtable pointer"),
1158             MMTuple(
1159               MMString("Simple C++ TBAA")),
1160             MConstInt(0)),
1161           MSameAs(0),
1162           MConstInt(0))));
1163   ASSERT_TRUE(I);
1164 
1165   I = matchNext(I,
1166       MInstruction(Instruction::Store,
1167         MConstInt(77, 32),
1168         MMTuple(
1169           ClassBase,
1170           MMTuple(
1171             MMString("int"),
1172             OmnipotentCharCXX,
1173             MConstInt(0)),
1174           MConstInt(0))));
1175   ASSERT_TRUE(I);
1176 }
1177 
1178 TEST(TBAAMetadataTest, TemplSpec) {
1179   const char TestProgram[] = R"**(
1180     template<typename T1, typename T2>
1181     struct ABC {
1182       T1 f1;
1183       T2 f2;
1184     };
1185 
1186     void func(ABC<double, int> *p) {
1187       p->f1 = 12.1;
1188       p->f2 = 44;
1189     }
1190   )**";
1191 
1192   clang::LangOptions LO;
1193   LO.CPlusPlus = 1;
1194   LO.CPlusPlus11 = 1;
1195   TBAATestCompiler Compiler(LO, TBAATestCompiler::getCommonCodeGenOpts());
1196   Compiler.init(TestProgram);
1197   const BasicBlock *BB = Compiler.compile();
1198 
1199   auto SpecABC = MMTuple(
1200     MMString("_ZTS3ABCIdiE"),
1201     MMTuple(
1202       MMString("double"),
1203       OmnipotentCharCXX,
1204       MConstInt(0)),
1205     MConstInt(0),
1206     MMTuple(
1207       MMString("int"),
1208       OmnipotentCharCXX,
1209       MConstInt(0)),
1210     MConstInt(8));
1211 
1212   const Instruction *I = match(BB,
1213       MInstruction(Instruction::Store,
1214         MValType(MType([](const Type &T)->bool { return T.isDoubleTy(); })),
1215         MMTuple(
1216           SpecABC,
1217           MMTuple(
1218             MMString("double"),
1219             OmnipotentCharCXX,
1220             MConstInt(0)),
1221           MConstInt(0))));
1222   ASSERT_TRUE(I);
1223 
1224   I = matchNext(I,
1225       MInstruction(Instruction::Store,
1226         MConstInt(44, 32),
1227         MMTuple(
1228           SpecABC,
1229           MMTuple(
1230             MMString("int"),
1231             OmnipotentCharCXX,
1232             MConstInt(0)),
1233           MConstInt(8))));
1234   ASSERT_TRUE(I);
1235 }
1236 }
1237