Clang Project

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