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