1 | |
2 | |
3 | |
4 | |
5 | |
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 | |
23 | using namespace llvm; |
24 | |
25 | namespace { |
26 | |
27 | struct 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(), false, false); |
76 | M = CG->GetModule(); |
77 | |
78 | |
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 | |
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 | |
103 | auto OmnipotentCharC = MMTuple( |
104 | MMString("omnipotent char"), |
105 | MMTuple( |
106 | MMString("Simple C/C++ TBAA")), |
107 | MConstInt(0, 64) |
108 | ); |
109 | |
110 | |
111 | auto OmnipotentCharCXX = MMTuple( |
112 | MMString("omnipotent char"), |
113 | MMTuple( |
114 | MMString("Simple C++ TBAA")), |
115 | MConstInt(0, 64) |
116 | ); |
117 | |
118 | |
119 | TEST(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(4, 8), |
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(11, 16), |
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(601, 32), |
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(604, 64), |
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 | |
207 | TEST(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(4, 32), |
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(11, 16), |
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(601, 64), |
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(22, 16), |
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(77, 32), |
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(604, 64), |
320 | MMTuple( |
321 | StructABC, |
322 | MMTuple( |
323 | MMString("long long"), |
324 | OmnipotentCharC, |
325 | MConstInt(0)), |
326 | MConstInt(24)))); |
327 | ASSERT_TRUE(I); |
328 | } |
329 | |
330 | TEST(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(4, 32), |
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(11, 16), |
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(44, 32), |
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(111, 16), |
408 | MMTuple( |
409 | NamelessStruct, |
410 | MMTuple( |
411 | MMString("short"), |
412 | OmnipotentCharC, |
413 | MConstInt(0)), |
414 | MConstInt(0)))); |
415 | ASSERT_TRUE(I); |
416 | |
417 | |
418 | |
419 | |
420 | } |
421 | |
422 | TEST(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(4, 32), |
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(11, 16), |
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(44, 32), |
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(111, 16), |
500 | MMTuple( |
501 | NamelessStruct, |
502 | MMTuple( |
503 | MMString("short"), |
504 | OmnipotentCharC, |
505 | MConstInt(0)), |
506 | MConstInt(0)))); |
507 | ASSERT_TRUE(I); |
508 | |
509 | |
510 | |
511 | |
512 | |
513 | } |
514 | |
515 | TEST(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(4, 32), |
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(11, 16), |
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(44, 32), |
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(111, 16), |
604 | MMTuple( |
605 | NamelessStruct2, |
606 | MMTuple( |
607 | MMString("short"), |
608 | OmnipotentCharC, |
609 | MConstInt(0)), |
610 | MConstInt(4)))); |
611 | ASSERT_TRUE(I); |
612 | } |
613 | |
614 | TEST(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(4, 32), |
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(11, 16), |
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(601, 64), |
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(22, 16), |
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(77, 32), |
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(604, 64), |
728 | MMTuple( |
729 | StructABC, |
730 | MMTuple( |
731 | MMString("long long"), |
732 | OmnipotentCharCXX, |
733 | MConstInt(0)), |
734 | MConstInt(24)))); |
735 | ASSERT_TRUE(I); |
736 | } |
737 | |
738 | TEST(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(4, 32), |
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(11, 16), |
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(44, 32), |
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(111, 16), |
828 | MMTuple( |
829 | StructCDE, |
830 | MMTuple( |
831 | MMString("short"), |
832 | OmnipotentCharCXX, |
833 | MConstInt(0)), |
834 | MConstInt(0)))); |
835 | ASSERT_TRUE(I); |
836 | } |
837 | |
838 | TEST(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(14, 16), |
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(35, 32), |
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(77, 32), |
910 | MMTuple( |
911 | StructOuter, |
912 | MMTuple( |
913 | MMString("int"), |
914 | OmnipotentCharCXX, |
915 | MConstInt(0)), |
916 | MConstInt(8)))); |
917 | ASSERT_TRUE(I); |
918 | } |
919 | |
920 | TEST(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, |
960 | MConstInt(4)); |
961 | |
962 | const Instruction *I = match(BB, |
963 | MInstruction(Instruction::Store, |
964 | MConstInt(14, 16), |
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(35, 32), |
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(77, 32), |
989 | MMTuple( |
990 | StructInner, |
991 | MMTuple( |
992 | MMString("int"), |
993 | OmnipotentCharCXX, |
994 | MConstInt(0)), |
995 | MConstInt(0)))); |
996 | ASSERT_TRUE(I); |
997 | } |
998 | |
999 | TEST(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(14, 32), |
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(35, 16), |
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(77, 32), |
1065 | MMTuple( |
1066 | ClassBase, |
1067 | MMTuple( |
1068 | MMString("int"), |
1069 | OmnipotentCharCXX, |
1070 | MConstInt(0)), |
1071 | MConstInt(0)))); |
1072 | ASSERT_TRUE(I); |
1073 | } |
1074 | |
1075 | TEST(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(14, 32), |
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(35, 16), |
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(77, 32), |
1143 | MMTuple( |
1144 | ClassBase, |
1145 | MMTuple( |
1146 | MMString("int"), |
1147 | OmnipotentCharCXX, |
1148 | MConstInt(0)), |
1149 | MConstInt(Compiler.PtrSize)))); |
1150 | ASSERT_TRUE(I); |
1151 | } |
1152 | |
1153 | TEST(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(14, 32), |
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(35, 16), |
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(77, 32), |
1231 | MMTuple( |
1232 | ClassBase, |
1233 | MMTuple( |
1234 | MMString("int"), |
1235 | OmnipotentCharCXX, |
1236 | MConstInt(0)), |
1237 | MConstInt(0)))); |
1238 | ASSERT_TRUE(I); |
1239 | } |
1240 | |
1241 | TEST(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(44, 32), |
1289 | MMTuple( |
1290 | SpecABC, |
1291 | MMTuple( |
1292 | MMString("int"), |
1293 | OmnipotentCharCXX, |
1294 | MConstInt(0)), |
1295 | MConstInt(8)))); |
1296 | ASSERT_TRUE(I); |
1297 | } |
1298 | } |
1299 | |