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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

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