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
20using namespace llvm;
21
22namespace {
23
24struct 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
35auto OmnipotentCharC = MMTuple(
36 Args: MMString(Name: "omnipotent char"),
37 Args: MMTuple(
38 Args: MMString(Name: "Simple C/C++ TBAA")),
39 Args: MConstInt(V: 0, W: 64)
40);
41
42
43auto OmnipotentCharCXX = MMTuple(
44 Args: MMString(Name: "omnipotent char"),
45 Args: MMTuple(
46 Args: MMString(Name: "Simple C++ TBAA")),
47 Args: MConstInt(V: 0, W: 64)
48);
49
50
51TEST(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 M: MInstruction(C: Instruction::Store,
71 Args: MConstInt(V: 4, W: 8),
72 Args: MMTuple(
73 Args: OmnipotentCharC,
74 Args: MSameAs(N: 0),
75 Args: MConstInt(V: 0))));
76 ASSERT_TRUE(I);
77
78 I = matchNext(I,
79 M: MInstruction(C: Instruction::Store,
80 Args: MConstInt(V: 11, W: 16),
81 Args: MMTuple(
82 Args: MMTuple(
83 Args: MMString(Name: "short"),
84 Args: OmnipotentCharC,
85 Args: MConstInt(V: 0)),
86 Args: MSameAs(N: 0),
87 Args: MConstInt(V: 0))));
88 ASSERT_TRUE(I);
89
90 I = matchNext(I,
91 M: MInstruction(C: Instruction::Store,
92 Args: MConstInt(V: 601, W: 32),
93 Args: MMTuple(
94 Args: MMTuple(
95 Args: MMString(Name: "int"),
96 Args: OmnipotentCharC,
97 Args: MConstInt(V: 0)),
98 Args: MSameAs(N: 0),
99 Args: MConstInt(V: 0))));
100 ASSERT_TRUE(I);
101
102 I = matchNext(I,
103 M: MInstruction(C: Instruction::Store,
104 Args: MConstInt(V: 604, W: 64),
105 Args: MMTuple(
106 Args: MMTuple(
107 Args: MMString(Name: "long long"),
108 Args: OmnipotentCharC,
109 Args: MConstInt(V: 0)),
110 Args: MSameAs(N: 0),
111 Args: MConstInt(V: 0))));
112 ASSERT_TRUE(I);
113
114 I = matchNext(I,
115 M: MInstruction(C: Instruction::Store,
116 Args: MValType(T: PointerType::getUnqual(C&: Compiler.Context)),
117 Args: MMTuple(
118 Args: MMTuple(
119 Args: MMString(Name: "any pointer"),
120 Args: OmnipotentCharC,
121 Args: MConstInt(V: 0)),
122 Args: MSameAs(N: 0),
123 Args: MConstInt(V: 0))));
124 ASSERT_TRUE(I);
125
126 I = matchNext(I,
127 M: MInstruction(C: Instruction::Store,
128 Args: MValType(T: PointerType::getUnqual(C&: Compiler.Context)),
129 Args: MMTuple(
130 Args: MMTuple(
131 Args: MMString(Name: "any pointer"),
132 Args: OmnipotentCharC,
133 Args: MConstInt(V: 0)),
134 Args: MSameAs(N: 0),
135 Args: MConstInt(V: 0))));
136 ASSERT_TRUE(I);
137}
138
139TEST(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 Args: MMString(Name: "ABC"),
168 Args: MMTuple(
169 Args: MMString(Name: "short"),
170 Args: OmnipotentCharC,
171 Args: MConstInt(V: 0)),
172 Args: MConstInt(V: 0),
173 Args: MMTuple(
174 Args: MMString(Name: "int"),
175 Args: OmnipotentCharC,
176 Args: MConstInt(V: 0)),
177 Args: MConstInt(V: 4),
178 Args: MMTuple(
179 Args: MMString(Name: "long long"),
180 Args: OmnipotentCharC,
181 Args: MConstInt(V: 0)),
182 Args: MConstInt(V: 8),
183 Args: MSameAs(N: 1),
184 Args: MConstInt(V: 16),
185 Args: MSameAs(N: 3),
186 Args: MConstInt(V: 20),
187 Args: MSameAs(N: 5),
188 Args: MConstInt(V: 24));
189
190 const Instruction *I = match(BB,
191 M: MInstruction(C: Instruction::Store,
192 Args: MConstInt(V: 4, W: 32),
193 Args: MMTuple(
194 Args: StructABC,
195 Args: MMTuple(
196 Args: MMString(Name: "int"),
197 Args: OmnipotentCharC,
198 Args: MConstInt(V: 0)),
199 Args: MConstInt(V: 4))));
200 ASSERT_TRUE(I);
201
202 I = matchNext(I,
203 M: MInstruction(C: Instruction::Store,
204 Args: MConstInt(V: 11, W: 16),
205 Args: MMTuple(
206 Args: StructABC,
207 Args: MMTuple(
208 Args: MMString(Name: "short"),
209 Args: OmnipotentCharC,
210 Args: MConstInt(V: 0)),
211 Args: MConstInt(V: 0))));
212 ASSERT_TRUE(I);
213
214 I = matchNext(I,
215 M: MInstruction(C: Instruction::Store,
216 Args: MConstInt(V: 601, W: 64),
217 Args: MMTuple(
218 Args: StructABC,
219 Args: MMTuple(
220 Args: MMString(Name: "long long"),
221 Args: OmnipotentCharC,
222 Args: MConstInt(V: 0)),
223 Args: MConstInt(V: 8))));
224 ASSERT_TRUE(I);
225
226 I = matchNext(I,
227 M: MInstruction(C: Instruction::Store,
228 Args: MConstInt(V: 22, W: 16),
229 Args: MMTuple(
230 Args: StructABC,
231 Args: MMTuple(
232 Args: MMString(Name: "short"),
233 Args: OmnipotentCharC,
234 Args: MConstInt(V: 0)),
235 Args: MConstInt(V: 16))));
236 ASSERT_TRUE(I);
237
238 I = matchNext(I,
239 M: MInstruction(C: Instruction::Store,
240 Args: MConstInt(V: 77, W: 32),
241 Args: MMTuple(
242 Args: StructABC,
243 Args: MMTuple(
244 Args: MMString(Name: "int"),
245 Args: OmnipotentCharC,
246 Args: MConstInt(V: 0)),
247 Args: MConstInt(V: 20))));
248 ASSERT_TRUE(I);
249
250 I = matchNext(I,
251 M: MInstruction(C: Instruction::Store,
252 Args: MConstInt(V: 604, W: 64),
253 Args: MMTuple(
254 Args: StructABC,
255 Args: MMTuple(
256 Args: MMString(Name: "long long"),
257 Args: OmnipotentCharC,
258 Args: MConstInt(V: 0)),
259 Args: MConstInt(V: 24))));
260 ASSERT_TRUE(I);
261}
262
263TEST(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 Args: MMString(Name: ""),
290 Args: MMTuple(
291 Args: MMString(Name: "short"),
292 Args: OmnipotentCharC,
293 Args: MConstInt(V: 0)),
294 Args: MConstInt(V: 0),
295 Args: MMTuple(
296 Args: MMString(Name: "int"),
297 Args: OmnipotentCharC,
298 Args: MConstInt(V: 0)),
299 Args: MConstInt(V: 4));
300
301 const Metadata *MetaABC = nullptr;
302 const Instruction *I = match(BB,
303 M: MInstruction(C: Instruction::Store,
304 Args: MConstInt(V: 4, W: 32),
305 Args: MMTuple(
306 Args: MMSave(V&: MetaABC, M: NamelessStruct),
307 Args: MMTuple(
308 Args: MMString(Name: "int"),
309 Args: OmnipotentCharC,
310 Args: MConstInt(V: 0)),
311 Args: MConstInt(V: 4))));
312 ASSERT_TRUE(I);
313
314 I = matchNext(I,
315 M: MInstruction(C: Instruction::Store,
316 Args: MConstInt(V: 11, W: 16),
317 Args: MMTuple(
318 Args: NamelessStruct,
319 Args: MMTuple(
320 Args: MMString(Name: "short"),
321 Args: OmnipotentCharC,
322 Args: MConstInt(V: 0)),
323 Args: MConstInt(V: 0))));
324 ASSERT_TRUE(I);
325
326 const Metadata *MetaCDE = nullptr;
327 I = matchNext(I,
328 M: MInstruction(C: Instruction::Store,
329 Args: MConstInt(V: 44, W: 32),
330 Args: MMTuple(
331 Args: MMSave(V&: MetaCDE, M: NamelessStruct),
332 Args: MMTuple(
333 Args: MMString(Name: "int"),
334 Args: OmnipotentCharC,
335 Args: MConstInt(V: 0)),
336 Args: MConstInt(V: 4))));
337 ASSERT_TRUE(I);
338
339 I = matchNext(I,
340 M: MInstruction(C: Instruction::Store,
341 Args: MConstInt(V: 111, W: 16),
342 Args: MMTuple(
343 Args: NamelessStruct,
344 Args: MMTuple(
345 Args: MMString(Name: "short"),
346 Args: OmnipotentCharC,
347 Args: MConstInt(V: 0)),
348 Args: MConstInt(V: 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
356TEST(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 Args: MMString(Name: ""),
383 Args: MMTuple(
384 Args: MMString(Name: "short"),
385 Args: OmnipotentCharC,
386 Args: MConstInt(V: 0)),
387 Args: MConstInt(V: 0),
388 Args: MMTuple(
389 Args: MMString(Name: "int"),
390 Args: OmnipotentCharC,
391 Args: MConstInt(V: 0)),
392 Args: MConstInt(V: 4));
393
394 const Metadata *MetaABC = nullptr;
395 const Instruction *I = match(BB,
396 M: MInstruction(C: Instruction::Store,
397 Args: MConstInt(V: 4, W: 32),
398 Args: MMTuple(
399 Args: MMSave(V&: MetaABC, M: NamelessStruct),
400 Args: MMTuple(
401 Args: MMString(Name: "int"),
402 Args: OmnipotentCharC,
403 Args: MConstInt(V: 0)),
404 Args: MConstInt(V: 4))));
405 ASSERT_TRUE(I);
406
407 I = matchNext(I,
408 M: MInstruction(C: Instruction::Store,
409 Args: MConstInt(V: 11, W: 16),
410 Args: MMTuple(
411 Args: NamelessStruct,
412 Args: MMTuple(
413 Args: MMString(Name: "short"),
414 Args: OmnipotentCharC,
415 Args: MConstInt(V: 0)),
416 Args: MConstInt(V: 0))));
417 ASSERT_TRUE(I);
418
419 const Metadata *MetaCDE = nullptr;
420 I = matchNext(I,
421 M: MInstruction(C: Instruction::Store,
422 Args: MConstInt(V: 44, W: 32),
423 Args: MMTuple(
424 Args: MMSave(V&: MetaCDE, M: NamelessStruct),
425 Args: MMTuple(
426 Args: MMString(Name: "int"),
427 Args: OmnipotentCharC,
428 Args: MConstInt(V: 0)),
429 Args: MConstInt(V: 4))));
430 ASSERT_TRUE(I);
431
432 I = matchNext(I,
433 M: MInstruction(C: Instruction::Store,
434 Args: MConstInt(V: 111, W: 16),
435 Args: MMTuple(
436 Args: NamelessStruct,
437 Args: MMTuple(
438 Args: MMString(Name: "short"),
439 Args: OmnipotentCharC,
440 Args: MConstInt(V: 0)),
441 Args: MConstInt(V: 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
450TEST(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 Args: MMString(Name: ""),
477 Args: MMTuple(
478 Args: MMString(Name: "short"),
479 Args: OmnipotentCharC,
480 Args: MConstInt(V: 0)),
481 Args: MConstInt(V: 0),
482 Args: MMTuple(
483 Args: MMString(Name: "int"),
484 Args: OmnipotentCharC,
485 Args: MConstInt(V: 0)),
486 Args: MConstInt(V: 4));
487
488 auto NamelessStruct2 = MMTuple(
489 Args: MMString(Name: ""),
490 Args: MMTuple(
491 Args: MMString(Name: "int"),
492 Args: OmnipotentCharC,
493 Args: MConstInt(V: 0)),
494 Args: MConstInt(V: 0),
495 Args: MMTuple(
496 Args: MMString(Name: "short"),
497 Args: OmnipotentCharC,
498 Args: MConstInt(V: 0)),
499 Args: MConstInt(V: 4));
500
501 const Instruction *I = match(BB,
502 M: MInstruction(C: Instruction::Store,
503 Args: MConstInt(V: 4, W: 32),
504 Args: MMTuple(
505 Args: NamelessStruct1,
506 Args: MMTuple(
507 Args: MMString(Name: "int"),
508 Args: OmnipotentCharC,
509 Args: MConstInt(V: 0)),
510 Args: MConstInt(V: 4))));
511 ASSERT_TRUE(I);
512
513 I = matchNext(I,
514 M: MInstruction(C: Instruction::Store,
515 Args: MConstInt(V: 11, W: 16),
516 Args: MMTuple(
517 Args: NamelessStruct1,
518 Args: MMTuple(
519 Args: MMString(Name: "short"),
520 Args: OmnipotentCharC,
521 Args: MConstInt(V: 0)),
522 Args: MConstInt(V: 0))));
523 ASSERT_TRUE(I);
524
525 I = matchNext(I,
526 M: MInstruction(C: Instruction::Store,
527 Args: MConstInt(V: 44, W: 32),
528 Args: MMTuple(
529 Args: NamelessStruct2,
530 Args: MMTuple(
531 Args: MMString(Name: "int"),
532 Args: OmnipotentCharC,
533 Args: MConstInt(V: 0)),
534 Args: MConstInt(V: 0))));
535 ASSERT_TRUE(I);
536
537 I = matchNext(I,
538 M: MInstruction(C: Instruction::Store,
539 Args: MConstInt(V: 111, W: 16),
540 Args: MMTuple(
541 Args: NamelessStruct2,
542 Args: MMTuple(
543 Args: MMString(Name: "short"),
544 Args: OmnipotentCharC,
545 Args: MConstInt(V: 0)),
546 Args: MConstInt(V: 4))));
547 ASSERT_TRUE(I);
548}
549
550TEST(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 Args: MMString(Name: "_ZTS3ABC"),
580 Args: MMTuple(
581 Args: MMString(Name: "short"),
582 Args: OmnipotentCharCXX,
583 Args: MConstInt(V: 0)),
584 Args: MConstInt(V: 0),
585 Args: MMTuple(
586 Args: MMString(Name: "int"),
587 Args: OmnipotentCharCXX,
588 Args: MConstInt(V: 0)),
589 Args: MConstInt(V: 4),
590 Args: MMTuple(
591 Args: MMString(Name: "long long"),
592 Args: OmnipotentCharCXX,
593 Args: MConstInt(V: 0)),
594 Args: MConstInt(V: 8),
595 Args: MSameAs(N: 1),
596 Args: MConstInt(V: 16),
597 Args: MSameAs(N: 3),
598 Args: MConstInt(V: 20),
599 Args: MSameAs(N: 5),
600 Args: MConstInt(V: 24));
601
602 const Instruction *I = match(BB,
603 M: MInstruction(C: Instruction::Store,
604 Args: MConstInt(V: 4, W: 32),
605 Args: MMTuple(
606 Args: StructABC,
607 Args: MMTuple(
608 Args: MMString(Name: "int"),
609 Args: OmnipotentCharCXX,
610 Args: MConstInt(V: 0)),
611 Args: MConstInt(V: 4))));
612 ASSERT_TRUE(I);
613
614 I = matchNext(I,
615 M: MInstruction(C: Instruction::Store,
616 Args: MConstInt(V: 11, W: 16),
617 Args: MMTuple(
618 Args: StructABC,
619 Args: MMTuple(
620 Args: MMString(Name: "short"),
621 Args: OmnipotentCharCXX,
622 Args: MConstInt(V: 0)),
623 Args: MConstInt(V: 0))));
624 ASSERT_TRUE(I);
625
626 I = matchNext(I,
627 M: MInstruction(C: Instruction::Store,
628 Args: MConstInt(V: 601, W: 64),
629 Args: MMTuple(
630 Args: StructABC,
631 Args: MMTuple(
632 Args: MMString(Name: "long long"),
633 Args: OmnipotentCharCXX,
634 Args: MConstInt(V: 0)),
635 Args: MConstInt(V: 8))));
636 ASSERT_TRUE(I);
637
638 I = matchNext(I,
639 M: MInstruction(C: Instruction::Store,
640 Args: MConstInt(V: 22, W: 16),
641 Args: MMTuple(
642 Args: StructABC,
643 Args: MMTuple(
644 Args: MMString(Name: "short"),
645 Args: OmnipotentCharCXX,
646 Args: MConstInt(V: 0)),
647 Args: MConstInt(V: 16))));
648 ASSERT_TRUE(I);
649
650 I = matchNext(I,
651 M: MInstruction(C: Instruction::Store,
652 Args: MConstInt(V: 77, W: 32),
653 Args: MMTuple(
654 Args: StructABC,
655 Args: MMTuple(
656 Args: MMString(Name: "int"),
657 Args: OmnipotentCharCXX,
658 Args: MConstInt(V: 0)),
659 Args: MConstInt(V: 20))));
660 ASSERT_TRUE(I);
661
662 I = matchNext(I,
663 M: MInstruction(C: Instruction::Store,
664 Args: MConstInt(V: 604, W: 64),
665 Args: MMTuple(
666 Args: StructABC,
667 Args: MMTuple(
668 Args: MMString(Name: "long long"),
669 Args: OmnipotentCharCXX,
670 Args: MConstInt(V: 0)),
671 Args: MConstInt(V: 24))));
672 ASSERT_TRUE(I);
673}
674
675TEST(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 Args: MMString(Name: "_ZTS3ABC"),
703 Args: MMTuple(
704 Args: MMString(Name: "short"),
705 Args: OmnipotentCharCXX,
706 Args: MConstInt(V: 0)),
707 Args: MConstInt(V: 0),
708 Args: MMTuple(
709 Args: MMString(Name: "int"),
710 Args: OmnipotentCharCXX,
711 Args: MConstInt(V: 0)),
712 Args: MConstInt(V: 4));
713
714 auto StructCDE = MMTuple(
715 Args: MMString(Name: "_ZTS3CDE"),
716 Args: MMTuple(
717 Args: MMString(Name: "short"),
718 Args: OmnipotentCharCXX,
719 Args: MConstInt(V: 0)),
720 Args: MConstInt(V: 0),
721 Args: MMTuple(
722 Args: MMString(Name: "int"),
723 Args: OmnipotentCharCXX,
724 Args: MConstInt(V: 0)),
725 Args: MConstInt(V: 4));
726
727 const Instruction *I = match(BB,
728 M: MInstruction(C: Instruction::Store,
729 Args: MConstInt(V: 4, W: 32),
730 Args: MMTuple(
731 Args: StructABC,
732 Args: MMTuple(
733 Args: MMString(Name: "int"),
734 Args: OmnipotentCharCXX,
735 Args: MConstInt(V: 0)),
736 Args: MConstInt(V: 4))));
737 ASSERT_TRUE(I);
738
739 I = matchNext(I,
740 M: MInstruction(C: Instruction::Store,
741 Args: MConstInt(V: 11, W: 16),
742 Args: MMTuple(
743 Args: StructABC,
744 Args: MMTuple(
745 Args: MMString(Name: "short"),
746 Args: OmnipotentCharCXX,
747 Args: MConstInt(V: 0)),
748 Args: MConstInt(V: 0))));
749 ASSERT_TRUE(I);
750
751 I = matchNext(I,
752 M: MInstruction(C: Instruction::Store,
753 Args: MConstInt(V: 44, W: 32),
754 Args: MMTuple(
755 Args: StructCDE,
756 Args: MMTuple(
757 Args: MMString(Name: "int"),
758 Args: OmnipotentCharCXX,
759 Args: MConstInt(V: 0)),
760 Args: MConstInt(V: 4))));
761 ASSERT_TRUE(I);
762
763 I = matchNext(I,
764 M: MInstruction(C: Instruction::Store,
765 Args: MConstInt(V: 111, W: 16),
766 Args: MMTuple(
767 Args: StructCDE,
768 Args: MMTuple(
769 Args: MMString(Name: "short"),
770 Args: OmnipotentCharCXX,
771 Args: MConstInt(V: 0)),
772 Args: MConstInt(V: 0))));
773 ASSERT_TRUE(I);
774}
775
776TEST(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 Args: MMString(Name: "_ZTS5Inner"),
804 Args: MMTuple(
805 Args: MMString(Name: "int"),
806 Args: OmnipotentCharCXX,
807 Args: MConstInt(V: 0)),
808 Args: MConstInt(V: 0));
809
810 auto StructOuter = MMTuple(
811 Args: MMString(Name: "_ZTS5Outer"),
812 Args: MMTuple(
813 Args: MMString(Name: "short"),
814 Args: OmnipotentCharCXX,
815 Args: MConstInt(V: 0)),
816 Args: MConstInt(V: 0),
817 Args: StructInner,
818 Args: MConstInt(V: 4),
819 Args: MSameAs(N: 3),
820 Args: MConstInt(V: 8));
821
822 const Instruction *I = match(BB,
823 M: MInstruction(C: Instruction::Store,
824 Args: MConstInt(V: 14, W: 16),
825 Args: MMTuple(
826 Args: StructOuter,
827 Args: MMTuple(
828 Args: MMString(Name: "short"),
829 Args: OmnipotentCharCXX,
830 Args: MConstInt(V: 0)),
831 Args: MConstInt(V: 0))));
832 ASSERT_TRUE(I);
833
834 I = matchNext(I,
835 M: MInstruction(C: Instruction::Store,
836 Args: MConstInt(V: 35, W: 32),
837 Args: MMTuple(
838 Args: StructOuter,
839 Args: MMTuple(
840 Args: MMString(Name: "int"),
841 Args: OmnipotentCharCXX,
842 Args: MConstInt(V: 0)),
843 Args: MConstInt(V: 4))));
844 ASSERT_TRUE(I);
845
846 I = matchNext(I,
847 M: MInstruction(C: Instruction::Store,
848 Args: MConstInt(V: 77, W: 32),
849 Args: MMTuple(
850 Args: StructOuter,
851 Args: MMTuple(
852 Args: MMString(Name: "int"),
853 Args: OmnipotentCharCXX,
854 Args: MConstInt(V: 0)),
855 Args: MConstInt(V: 8))));
856 ASSERT_TRUE(I);
857}
858
859TEST(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 Args: MMString(Name: "_ZTS5Inner"),
886 Args: MMTuple(
887 Args: MMString(Name: "int"),
888 Args: OmnipotentCharCXX,
889 Args: MConstInt(V: 0)),
890 Args: MConstInt(V: 0));
891
892 auto StructOuter = MMTuple(
893 Args: MMString(Name: "_ZTS5Outer"),
894 Args: MMTuple(
895 Args: MMString(Name: "short"),
896 Args: OmnipotentCharCXX,
897 Args: MConstInt(V: 0)),
898 Args: MConstInt(V: 0),
899 Args: OmnipotentCharCXX, // FIXME: Info about array field is lost.
900 Args: MConstInt(V: 4));
901
902 const Instruction *I = match(BB,
903 M: MInstruction(C: Instruction::Store,
904 Args: MConstInt(V: 14, W: 16),
905 Args: MMTuple(
906 Args: StructOuter,
907 Args: MMTuple(
908 Args: MMString(Name: "short"),
909 Args: OmnipotentCharCXX,
910 Args: MConstInt(V: 0)),
911 Args: MConstInt(V: 0))));
912 ASSERT_TRUE(I);
913
914 I = matchNext(I,
915 M: MInstruction(C: Instruction::Store,
916 Args: MConstInt(V: 35, W: 32),
917 Args: MMTuple(
918 Args: StructInner,
919 Args: MMTuple(
920 Args: MMString(Name: "int"),
921 Args: OmnipotentCharCXX,
922 Args: MConstInt(V: 0)),
923 Args: MConstInt(V: 0))));
924 ASSERT_TRUE(I);
925
926 I = matchNext(I,
927 M: MInstruction(C: Instruction::Store,
928 Args: MConstInt(V: 77, W: 32),
929 Args: MMTuple(
930 Args: StructInner,
931 Args: MMTuple(
932 Args: MMString(Name: "int"),
933 Args: OmnipotentCharCXX,
934 Args: MConstInt(V: 0)),
935 Args: MConstInt(V: 0))));
936 ASSERT_TRUE(I);
937}
938
939TEST(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 Args: MMString(Name: "_ZTS4Base"),
965 Args: MMTuple(
966 Args: MMString(Name: "int"),
967 Args: OmnipotentCharCXX,
968 Args: MConstInt(V: 0)),
969 Args: MConstInt(V: 0));
970
971 auto ClassDerived =
972 MMTuple(Args: MMString(Name: "_ZTS7Derived"), Args: ClassBase, Args: MConstInt(V: 0),
973 Args: MMTuple(Args: MMString(Name: "short"), Args: OmnipotentCharCXX, Args: MConstInt(V: 0)),
974 Args: MConstInt(V: 4));
975
976 const Instruction *I = match(BB,
977 M: MInstruction(C: Instruction::Store,
978 Args: MConstInt(V: 14, W: 32),
979 Args: MMTuple(
980 Args: ClassBase,
981 Args: MMTuple(
982 Args: MMString(Name: "int"),
983 Args: OmnipotentCharCXX,
984 Args: MConstInt(V: 0)),
985 Args: MConstInt(V: 0))));
986 ASSERT_TRUE(I);
987
988 I = matchNext(I,
989 M: MInstruction(C: Instruction::Store,
990 Args: MConstInt(V: 35, W: 16),
991 Args: MMTuple(
992 Args: ClassDerived,
993 Args: MMTuple(
994 Args: MMString(Name: "short"),
995 Args: OmnipotentCharCXX,
996 Args: MConstInt(V: 0)),
997 Args: MConstInt(V: 4))));
998 ASSERT_TRUE(I);
999
1000 I = matchNext(I,
1001 M: MInstruction(C: Instruction::Store,
1002 Args: MConstInt(V: 77, W: 32),
1003 Args: MMTuple(
1004 Args: ClassBase,
1005 Args: MMTuple(
1006 Args: MMString(Name: "int"),
1007 Args: OmnipotentCharCXX,
1008 Args: MConstInt(V: 0)),
1009 Args: MConstInt(V: 0))));
1010 ASSERT_TRUE(I);
1011}
1012
1013TEST(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 Args: MMString(Name: "_ZTS4Base"),
1041 Args: MMTuple(
1042 Args: MMString(Name: "int"),
1043 Args: OmnipotentCharCXX,
1044 Args: MConstInt(V: 0)),
1045 Args: MConstInt(V: Compiler.PtrSize));
1046
1047 auto ClassDerived =
1048 MMTuple(Args: MMString(Name: "_ZTS7Derived"), Args: ClassBase, Args: MConstInt(V: 0),
1049 Args: MMTuple(Args: MMString(Name: "short"), Args: OmnipotentCharCXX, Args: MConstInt(V: 0)),
1050 Args: MConstInt(V: Compiler.PtrSize + 4));
1051
1052 const Instruction *I = match(BB,
1053 M: MInstruction(C: Instruction::Store,
1054 Args: MConstInt(V: 14, W: 32),
1055 Args: MMTuple(
1056 Args: ClassBase,
1057 Args: MMTuple(
1058 Args: MMString(Name: "int"),
1059 Args: OmnipotentCharCXX,
1060 Args: MConstInt(V: 0)),
1061 Args: MConstInt(V: Compiler.PtrSize))));
1062 ASSERT_TRUE(I);
1063
1064 I = matchNext(I,
1065 M: MInstruction(C: Instruction::Store,
1066 Args: MConstInt(V: 35, W: 16),
1067 Args: MMTuple(
1068 Args: ClassDerived,
1069 Args: MMTuple(
1070 Args: MMString(Name: "short"),
1071 Args: OmnipotentCharCXX,
1072 Args: MConstInt(V: 0)),
1073 Args: MConstInt(V: Compiler.PtrSize + 4))));
1074 ASSERT_TRUE(I);
1075
1076 I = matchNext(I,
1077 M: MInstruction(C: Instruction::Store,
1078 Args: MConstInt(V: 77, W: 32),
1079 Args: MMTuple(
1080 Args: ClassBase,
1081 Args: MMTuple(
1082 Args: MMString(Name: "int"),
1083 Args: OmnipotentCharCXX,
1084 Args: MConstInt(V: 0)),
1085 Args: MConstInt(V: Compiler.PtrSize))));
1086 ASSERT_TRUE(I);
1087}
1088
1089TEST(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 Args: MMString(Name: "_ZTS4Base"),
1115 Args: MMTuple(
1116 Args: MMString(Name: "int"),
1117 Args: OmnipotentCharCXX,
1118 Args: MConstInt(V: 0)),
1119 Args: MConstInt(V: 0));
1120
1121 auto ClassDerived = MMTuple(
1122 Args: MMString(Name: "_ZTS7Derived"),
1123 Args: MMTuple(
1124 Args: MMString(Name: "short"),
1125 Args: OmnipotentCharCXX,
1126 Args: MConstInt(V: 0)),
1127 Args: MConstInt(V: Compiler.PtrSize));
1128
1129 const Instruction *I = match(BB,
1130 M: MInstruction(C: Instruction::Store,
1131 Args: MConstInt(V: 14, W: 32),
1132 Args: MMTuple(
1133 Args: ClassBase,
1134 Args: MMTuple(
1135 Args: MMString(Name: "int"),
1136 Args: OmnipotentCharCXX,
1137 Args: MConstInt(V: 0)),
1138 Args: MConstInt(V: 0))));
1139 ASSERT_TRUE(I);
1140
1141 I = matchNext(I,
1142 M: MInstruction(C: Instruction::Store,
1143 Args: MConstInt(V: 35, W: 16),
1144 Args: MMTuple(
1145 Args: ClassDerived,
1146 Args: MMTuple(
1147 Args: MMString(Name: "short"),
1148 Args: OmnipotentCharCXX,
1149 Args: MConstInt(V: 0)),
1150 Args: MConstInt(V: Compiler.PtrSize))));
1151 ASSERT_TRUE(I);
1152
1153 I = matchNext(I,
1154 M: MInstruction(C: Instruction::Load,
1155 Args: MMTuple(
1156 Args: MMTuple(
1157 Args: MMString(Name: "vtable pointer"),
1158 Args: MMTuple(
1159 Args: MMString(Name: "Simple C++ TBAA")),
1160 Args: MConstInt(V: 0)),
1161 Args: MSameAs(N: 0),
1162 Args: MConstInt(V: 0))));
1163 ASSERT_TRUE(I);
1164
1165 I = matchNext(I,
1166 M: MInstruction(C: Instruction::Store,
1167 Args: MConstInt(V: 77, W: 32),
1168 Args: MMTuple(
1169 Args: ClassBase,
1170 Args: MMTuple(
1171 Args: MMString(Name: "int"),
1172 Args: OmnipotentCharCXX,
1173 Args: MConstInt(V: 0)),
1174 Args: MConstInt(V: 0))));
1175 ASSERT_TRUE(I);
1176}
1177
1178TEST(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 Args: MMString(Name: "_ZTS3ABCIdiE"),
1201 Args: MMTuple(
1202 Args: MMString(Name: "double"),
1203 Args: OmnipotentCharCXX,
1204 Args: MConstInt(V: 0)),
1205 Args: MConstInt(V: 0),
1206 Args: MMTuple(
1207 Args: MMString(Name: "int"),
1208 Args: OmnipotentCharCXX,
1209 Args: MConstInt(V: 0)),
1210 Args: MConstInt(V: 8));
1211
1212 const Instruction *I = match(BB,
1213 M: MInstruction(C: Instruction::Store,
1214 Args: MValType(T: MType(C: [](const Type &T)->bool { return T.isDoubleTy(); })),
1215 Args: MMTuple(
1216 Args: SpecABC,
1217 Args: MMTuple(
1218 Args: MMString(Name: "double"),
1219 Args: OmnipotentCharCXX,
1220 Args: MConstInt(V: 0)),
1221 Args: MConstInt(V: 0))));
1222 ASSERT_TRUE(I);
1223
1224 I = matchNext(I,
1225 M: MInstruction(C: Instruction::Store,
1226 Args: MConstInt(V: 44, W: 32),
1227 Args: MMTuple(
1228 Args: SpecABC,
1229 Args: MMTuple(
1230 Args: MMString(Name: "int"),
1231 Args: OmnipotentCharCXX,
1232 Args: MConstInt(V: 0)),
1233 Args: MConstInt(V: 8))));
1234 ASSERT_TRUE(I);
1235}
1236}
1237

source code of clang/unittests/CodeGen/TBAAMetadataTest.cpp