clang: lib/Analysis/FlowSensitive/Transfer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
35#include "llvm/Support/Casting.h"
37#include
38
39#define DEBUG_TYPE "dataflow"
40
42namespace dataflow {
43
46 if (Block == nullptr) {
47 assert(false);
48 return nullptr;
49 }
50 if (!ACFG.isBlockReachable(*Block))
51 return nullptr;
52 if (Block->getBlockID() == CurBlockID)
53 return &CurState.Env;
54 const auto &State = BlockToState[Block->getBlockID()];
55 if (!(State))
56 return nullptr;
57 return &State->Env;
58}
59
64
65
66
67 if (LHSValue == RHSValue && LHSValue)
69
70
71
74
75 if (auto *LHSBool = dyn_cast_or_null(LHSValue))
76 if (auto *RHSBool = dyn_cast_or_null(RHSValue))
77 return Env.makeIff(*LHSBool, *RHSBool);
78
79 if (auto *LHSPtr = dyn_cast_or_null(LHSValue))
80 if (auto *RHSPtr = dyn_cast_or_null(RHSValue))
81
82
83
84 if (&LHSPtr->getPointeeLoc() == &RHSPtr->getPointeeLoc())
86
88}
89
91 if (auto *Top = llvm::dyn_cast(&V)) {
93 return A.makeBoolValue(A.makeAtomRef(Top->getAtom()));
94 }
95 return V;
96}
97
98
99
100
103 if (Loc == nullptr)
104 return nullptr;
105 auto *Val = Env.getValue(*Loc);
106
107 auto *B = dyn_cast_or_null(Val);
108 if (B == nullptr)
109 return Val;
110
111 auto &UnpackedVal = unpackValue(*B, Env);
112 if (&UnpackedVal == Val)
113 return Val;
114 Env.setValue(*Loc, UnpackedVal);
115 return &UnpackedVal;
116}
117
120 return;
121 if (auto *Val = Env.getValue(From))
123}
124
130
131
132
133
142
143namespace {
144
145class TransferVisitor : public ConstStmtVisitor {
146public:
147 TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env,
148 Environment::ValueModel &Model)
149 : StmtToEnv(StmtToEnv), Env(Env), Model(Model) {}
150
151 void VisitBinaryOperator(const BinaryOperator *S) {
152 const Expr *LHS = S->getLHS();
153 assert(LHS != nullptr);
154
155 const Expr *RHS = S->getRHS();
156 assert(RHS != nullptr);
157
158
159
160
161
162 if (S->isCompoundAssignmentOp())
164
165 switch (S->getOpcode()) {
166 case BO_Assign: {
167 auto *LHSLoc = Env.getStorageLocation(*LHS);
168 if (LHSLoc == nullptr)
169 break;
170
171 auto *RHSVal = Env.getValue(*RHS);
172 if (RHSVal == nullptr)
173 break;
174
175
176 Env.setValue(*LHSLoc, *RHSVal);
177
178
179 Env.setStorageLocation(*S, *LHSLoc);
180 break;
181 }
182 case BO_LAnd:
183 case BO_LOr: {
184 BoolValue &LHSVal = getLogicOperatorSubExprValue(*LHS);
185 BoolValue &RHSVal = getLogicOperatorSubExprValue(*RHS);
186
187 if (S->getOpcode() == BO_LAnd)
188 Env.setValue(*S, Env.makeAnd(LHSVal, RHSVal));
189 else
190 Env.setValue(*S, Env.makeOr(LHSVal, RHSVal));
191 break;
192 }
193 case BO_NE:
194 case BO_EQ: {
196 Env.setValue(*S, S->getOpcode() == BO_EQ ? LHSEqRHSValue
197 : Env.makeNot(LHSEqRHSValue));
198 break;
199 }
200 case BO_Comma: {
202 break;
203 }
204 default:
205 break;
206 }
207 }
208
209 void VisitDeclRefExpr(const DeclRefExpr *S) {
210 const ValueDecl *VD = S->getDecl();
211 assert(VD != nullptr);
212
213
214
215
216
217
218
219
220
221
222 if (!S->isGLValue())
223 return;
224
225 auto *DeclLoc = Env.getStorageLocation(*VD);
226 if (DeclLoc == nullptr)
227 return;
228
229 Env.setStorageLocation(*S, *DeclLoc);
230 }
231
232 void VisitDeclStmt(const DeclStmt *S) {
233
234
235 const auto &D = *cast(S->getSingleDecl());
236
237 ProcessVarDecl(D);
238 }
239
240 void ProcessVarDecl(const VarDecl &D) {
241
242 if (D.hasGlobalStorage())
243 return;
244
245
246
247
248 if (D.getType()->isReferenceType() && Env.getStorageLocation(D) != nullptr)
249 return;
250
251 assert(Env.getStorageLocation(D) == nullptr);
252
253 Env.setStorageLocation(D, Env.createObject(D));
254
255
256
257
258 if (const auto *Decomp = dyn_cast(&D)) {
259
260
261
262
263
264 for (const auto *B : Decomp->bindings()) {
265 if (auto *ME = dyn_cast_or_null(B->getBinding())) {
266 auto *DE = dyn_cast_or_null(ME->getBase());
267 if (DE == nullptr)
268 continue;
269
270
271
272 VisitDeclRefExpr(DE);
273 VisitMemberExpr(ME);
274
275 if (auto *Loc = Env.getStorageLocation(*ME))
276 Env.setStorageLocation(*B, *Loc);
277 } else if (auto *VD = B->getHoldingVar()) {
278
279
280
281
282
283
284 ProcessVarDecl(*VD);
285 auto *VDLoc = Env.getStorageLocation(*VD);
286 assert(VDLoc != nullptr);
287 Env.setStorageLocation(*B, *VDLoc);
288 }
289 }
290 }
291 }
292
293 void VisitCastExpr(const CastExpr *S) {
294 const Expr *SubExpr = S->getSubExpr();
295 assert(SubExpr != nullptr);
296
297 switch (S->getCastKind()) {
298 case CK_IntegralToBoolean: {
299
300
301
302 if (auto *SubExprVal =
303 dyn_cast_or_null(Env.getValue(*SubExpr)))
304 Env.setValue(*S, *SubExprVal);
305 else
306
307
308 Env.setValue(*S, Env.makeAtomicBoolValue());
309 break;
310 }
311
312 case CK_LValueToRValue: {
313
314
316 if (SubExprVal == nullptr)
317 break;
318
319 Env.setValue(*S, *SubExprVal);
320 break;
321 }
322
323 case CK_BaseToDerived: {
324
325
326
327
328 RecordStorageLocation *Loc = nullptr;
329 if (S->getType()->isPointerType()) {
330 auto *PV = Env.get(*SubExpr);
331 assert(PV != nullptr);
332 if (PV == nullptr)
333 break;
335 } else {
336 assert(S->getType()->isRecordType());
337 if (SubExpr->isGLValue()) {
338 Loc = Env.get(*SubExpr);
339 } else {
340 Loc = &Env.getResultObjectLocation(*SubExpr);
341 }
342 }
343 if (!Loc) {
344
345 break;
346 }
347
348
349 QualType Derived = S->getType().getNonReferenceType();
350 if (Derived->isPointerType()) {
351 Derived = Derived->getPointeeType();
352 }
353
354
355
356 for (const FieldDecl *Field :
357 Env.getDataflowAnalysisContext().getModeledFields(Derived)) {
358 assert(Field != nullptr);
359 QualType FieldType = Field->getType();
360 if (FieldType->isReferenceType()) {
361 Loc->addChild(*Field, nullptr);
362 } else {
363 Loc->addChild(*Field, &Env.createStorageLocation(FieldType));
364 }
365
366 for (const auto &Entry :
367 Env.getDataflowAnalysisContext().getSyntheticFields(Derived)) {
368 Loc->addSyntheticField(Entry.getKey(),
369 Env.createStorageLocation(Entry.getValue()));
370 }
371 }
372 Env.initializeFieldsWithValues(*Loc, Derived);
373
374
375 [[fallthrough]];
376 }
377 case CK_IntegralCast:
378
379
380
381
382
383 case CK_UncheckedDerivedToBase:
384 case CK_DerivedToBase:
385 case CK_ConstructorConversion:
386 case CK_UserDefinedConversion:
387 case CK_NoOp: {
388
389
390
392 break;
393 }
394 case CK_NullToPointer: {
395 auto &NullPointerVal =
396 Env.getOrCreateNullPointerValue(S->getType()->getPointeeType());
397 Env.setValue(*S, NullPointerVal);
398 break;
399 }
400 case CK_NullToMemberPointer:
401
402
403 break;
404 case CK_FunctionToPointerDecay: {
405 StorageLocation *PointeeLoc = Env.getStorageLocation(*SubExpr);
406 if (PointeeLoc == nullptr)
407 break;
408
409 Env.setValue(*S, Env.create(*PointeeLoc));
410 break;
411 }
412 case CK_BuiltinFnToFnPtr:
413
414
415
416
417 break;
418 default:
419 break;
420 }
421 }
422
423 void VisitUnaryOperator(const UnaryOperator *S) {
424 const Expr *SubExpr = S->getSubExpr();
425 assert(SubExpr != nullptr);
426
427 switch (S->getOpcode()) {
428 case UO_Deref: {
429 const auto *SubExprVal = Env.get(*SubExpr);
430 if (SubExprVal == nullptr)
431 break;
432
433 Env.setStorageLocation(*S, SubExprVal->getPointeeLoc());
434 break;
435 }
436 case UO_AddrOf: {
437
438 if (S->getType()->isMemberPointerType())
439 break;
440
441 if (StorageLocation *PointeeLoc = Env.getStorageLocation(*SubExpr))
442 Env.setValue(*S, Env.create(*PointeeLoc));
443 break;
444 }
445 case UO_LNot: {
446 auto *SubExprVal = dyn_cast_or_null(Env.getValue(*SubExpr));
447 if (SubExprVal == nullptr)
448 break;
449
450 Env.setValue(*S, Env.makeNot(*SubExprVal));
451 break;
452 }
453 case UO_PreInc:
454 case UO_PreDec:
455
456
457
458
460 if (StorageLocation *Loc = Env.getStorageLocation(*S->getSubExpr()))
461 Env.clearValue(*Loc);
462 break;
463 case UO_PostInc:
464 case UO_PostDec:
465
466
467
469 if (StorageLocation *Loc = Env.getStorageLocation(*S->getSubExpr()))
470 Env.clearValue(*Loc);
471 break;
472 default:
473 break;
474 }
475 }
476
477 void VisitCXXThisExpr(const CXXThisExpr *S) {
478 auto *ThisPointeeLoc = Env.getThisPointeeStorageLocation();
479 if (ThisPointeeLoc == nullptr)
480
481
482 return;
483
484 Env.setValue(*S, Env.create(*ThisPointeeLoc));
485 }
486
487 void VisitCXXNewExpr(const CXXNewExpr *S) {
488 if (Value *Val = Env.createValue(S->getType()))
489 Env.setValue(*S, *Val);
490 }
491
492 void VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
493
494
495
496
497 }
498
499 void VisitReturnStmt(const ReturnStmt *S) {
500 if (!Env.getDataflowAnalysisContext().getOptions().ContextSensitiveOpts)
501 return;
502
503 auto *Ret = S->getRetValue();
504 if (Ret == nullptr)
505 return;
506
507 if (Ret->isPRValue()) {
508 if (Ret->getType()->isRecordType())
509 return;
510
511 auto *Val = Env.getValue(*Ret);
512 if (Val == nullptr)
513 return;
514
515
516 Env.setReturnValue(Val);
517 } else {
518 auto *Loc = Env.getStorageLocation(*Ret);
519 if (Loc == nullptr)
520 return;
521
522
523 Env.setReturnStorageLocation(Loc);
524 }
525 }
526
527 void VisitMemberExpr(const MemberExpr *S) {
528 ValueDecl *Member = S->getMemberDecl();
529 assert(Member != nullptr);
530
531
532 if (Member->isFunctionOrFunctionTemplate())
533 return;
534
535
537 return;
538
539 if (auto *D = dyn_cast(Member)) {
540 if (D->hasGlobalStorage()) {
541 auto *VarDeclLoc = Env.getStorageLocation(*D);
542 if (VarDeclLoc == nullptr)
543 return;
544
545 Env.setStorageLocation(*S, *VarDeclLoc);
546 return;
547 }
548 }
549
551 if (BaseLoc == nullptr)
552 return;
553
554 auto *MemberLoc = BaseLoc->getChild(*Member);
555 if (MemberLoc == nullptr)
556 return;
557 Env.setStorageLocation(*S, *MemberLoc);
558 }
559
560 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
561 const Expr *ArgExpr = S->getExpr();
562 assert(ArgExpr != nullptr);
564
565 if (S->isPRValue() && S->getType()->isRecordType()) {
566 auto &Loc = Env.getResultObjectLocation(*S);
567 Env.initializeFieldsWithValues(Loc);
568 }
569 }
570
571 void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
572 const Expr *InitExpr = S->getExpr();
573 assert(InitExpr != nullptr);
574
575
576
577
578 if (S->getType()->isRecordType() && S->isPRValue())
579 return;
580
582 }
583
584 void VisitCXXConstructExpr(const CXXConstructExpr *S) {
585 const CXXConstructorDecl *ConstructorDecl = S->getConstructor();
586 assert(ConstructorDecl != nullptr);
587
588
589
590
591 if (!S->getType()->isRecordType()) {
592 transferInlineCall(S, ConstructorDecl);
593 return;
594 }
595
596 RecordStorageLocation &Loc = Env.getResultObjectLocation(*S);
597
598 if (ConstructorDecl->isCopyOrMoveConstructor()) {
599
600
601 assert(S->getNumArgs() != 0);
602
603 const Expr *Arg = S->getArg(0);
604 assert(Arg != nullptr);
605
606 auto *ArgLoc = Env.get(*Arg);
607 if (ArgLoc == nullptr)
608 return;
609
610
611
612
613
614
615
616
617
618
619
620
621 copyRecord(*ArgLoc, Loc, Env, S->getType());
622 return;
623 }
624
625 Env.initializeFieldsWithValues(Loc, S->getType());
626
627 transferInlineCall(S, ConstructorDecl);
628 }
629
630 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
631 if (S->getOperator() == OO_Equal) {
632 assert(S->getNumArgs() == 2);
633
634 const Expr *Arg0 = S->getArg(0);
635 assert(Arg0 != nullptr);
636
637 const Expr *Arg1 = S->getArg(1);
638 assert(Arg1 != nullptr);
639
640
642 dyn_cast_or_null(S->getDirectCallee());
644 return;
645 if (->isCopyAssignmentOperator() &&
646 ->isMoveAssignmentOperator())
647 return;
648
649 RecordStorageLocation *LocSrc = nullptr;
650 if (Arg1->isPRValue()) {
651 LocSrc = &Env.getResultObjectLocation(*Arg1);
652 } else {
653 LocSrc = Env.get(*Arg1);
654 }
655 auto *LocDst = Env.get(*Arg0);
656
657 if (LocSrc == nullptr || LocDst == nullptr)
658 return;
659
660
661
662
663
664
665 copyRecord(*LocSrc, *LocDst, Env, Arg0->getType());
666
667
668
669
670 if (S->getType().getCanonicalType().getUnqualifiedType() !=
671 LocDst->getType().getCanonicalType().getUnqualifiedType()) {
672 auto ReturnDecl = S->getType()->getAsCXXRecordDecl();
673 auto DstDecl = LocDst->getType()->getAsCXXRecordDecl();
674 if (ReturnDecl == nullptr || DstDecl == nullptr)
675 return;
676 if (!DstDecl->isDerivedFrom(ReturnDecl))
677 return;
678 }
679
680 if (S->isGLValue())
681 Env.setStorageLocation(*S, *LocDst);
682 else
683 copyRecord(*LocDst, Env.getResultObjectLocation(*S), Env);
684
685 return;
686 }
687
688
689
690 VisitCallExpr(S);
691 }
692
693 void VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *RBO) {
695 }
696
697 void VisitCallExpr(const CallExpr *S) {
698
699
700
701 if (S->isCallToStdMove()) {
702 assert(S->getNumArgs() == 1);
703
704 const Expr *Arg = S->getArg(0);
705 assert(Arg != nullptr);
706
707 auto *ArgLoc = Env.getStorageLocation(*Arg);
708 if (ArgLoc == nullptr)
709 return;
710
711 Env.setStorageLocation(*S, *ArgLoc);
712 } else if (S->getDirectCallee() != nullptr &&
713 S->getDirectCallee()->getBuiltinID() ==
714 Builtin::BI__builtin_expect) {
715 assert(S->getNumArgs() > 0);
716 assert(S->getArg(0) != nullptr);
717 auto *ArgVal = Env.getValue(*S->getArg(0));
718 if (ArgVal == nullptr)
719 return;
720 Env.setValue(*S, *ArgVal);
721 } else if (const FunctionDecl *F = S->getDirectCallee()) {
722 transferInlineCall(S, F);
723
724
725
726 if (S->getType()->isRecordType() && S->isPRValue()) {
727 RecordStorageLocation &Loc = Env.getResultObjectLocation(*S);
728 Env.initializeFieldsWithValues(Loc);
729 }
730 }
731 }
732
733 void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *S) {
734 const Expr *SubExpr = S->getSubExpr();
735 assert(SubExpr != nullptr);
736
737 StorageLocation &Loc = Env.createStorageLocation(*S);
738 Env.setStorageLocation(*S, Loc);
739
740 if (SubExpr->getType()->isRecordType())
741
742
743 return;
744
745 if (Value *SubExprVal = Env.getValue(*SubExpr))
746 Env.setValue(Loc, *SubExprVal);
747 }
748
749 void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
750 const Expr *SubExpr = S->getSubExpr();
751 assert(SubExpr != nullptr);
752
754 }
755
756 void VisitConditionalOperator(const ConditionalOperator *S) {
757 const Environment *TrueEnv = StmtToEnv.getEnvironment(*S->getTrueExpr());
758 const Environment *FalseEnv = StmtToEnv.getEnvironment(*S->getFalseExpr());
759
760 if (TrueEnv == nullptr || FalseEnv == nullptr) {
761
762
763
764
765 return;
766 }
767
768 if (S->isGLValue()) {
769 StorageLocation *TrueLoc = TrueEnv->getStorageLocation(*S->getTrueExpr());
770 StorageLocation *FalseLoc =
771 FalseEnv->getStorageLocation(*S->getFalseExpr());
772 if (TrueLoc == FalseLoc && TrueLoc != nullptr) {
773 Env.setStorageLocation(*S, *TrueLoc);
774 } else if (!S->getType()->isRecordType()) {
775
776
777
778
779
780
781
782
783
784
785
787 S->getType(), TrueEnv->getValue(*S->getTrueExpr()), *TrueEnv,
788 FalseEnv->getValue(*S->getFalseExpr()), *FalseEnv, Env,
789 Model)) {
790 StorageLocation &Loc = Env.createStorageLocation(*S);
791 Env.setStorageLocation(*S, Loc);
792 Env.setValue(Loc, *Val);
793 }
794 }
795 } else if (!S->getType()->isRecordType()) {
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
812 S->getType(), TrueEnv->getValue(*S->getTrueExpr()), *TrueEnv,
813 FalseEnv->getValue(*S->getFalseExpr()), *FalseEnv, Env, Model))
814 Env.setValue(*S, *Val);
815 }
816 }
817
818 void VisitInitListExpr(const InitListExpr *S) {
819 QualType Type = S->getType();
820
821 if (->isRecordType()) {
822
823
824 if (->isArrayType() && S->getNumInits() == 1)
826 return;
827 }
828
829
830 if (S->isSemanticForm() && S->isTransparent())
831 return;
832
833 RecordStorageLocation &Loc = Env.getResultObjectLocation(*S);
834
835
836
837
838
839
840 RecordInitListHelper InitListHelper(S);
841
842 for (auto [Field, Init] : InitListHelper.field_inits()) {
843 if (Field->getType()->isRecordType())
844 continue;
845 if (Field->getType()->isReferenceType()) {
846 assert(Field->getType().getCanonicalType()->getPointeeType() ==
847 Init->getType().getCanonicalType());
848 Loc.setChild(*Field, &Env.createObject(Field->getType(), Init));
849 continue;
850 }
851 assert(Field->getType().getCanonicalType().getUnqualifiedType() ==
852 Init->getType().getCanonicalType().getUnqualifiedType());
853 StorageLocation *FieldLoc = Loc.getChild(*Field);
854
855 assert(FieldLoc != nullptr);
856 Value *Val = Env.getValue(*Init);
858 Init->getType()->isPointerType())
859 Val =
860 &Env.getOrCreateNullPointerValue(Init->getType()->getPointeeType());
861 if (Val == nullptr)
862 Val = Env.createValue(Field->getType());
863 if (Val != nullptr)
864 Env.setValue(*FieldLoc, *Val);
865 }
866
867 for (const auto &[FieldName, FieldLoc] : Loc.synthetic_fields()) {
868 QualType FieldType = FieldLoc->getType();
869 if (FieldType->isRecordType()) {
871 } else {
872 if (Value *Val = Env.createValue(FieldType))
873 Env.setValue(*FieldLoc, *Val);
874 }
875 }
876
877
878 }
879
880 void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
881 Env.setValue(*S, Env.getBoolLiteralValue(S->getValue()));
882 }
883
884 void VisitIntegerLiteral(const IntegerLiteral *S) {
885 Env.setValue(*S, Env.getIntLiteralValue(S->getValue()));
886 }
887
888 void VisitParenExpr(const ParenExpr *S) {
889
890
891
892 auto *SubExpr = S->getSubExpr();
893 assert(SubExpr != nullptr);
894 Visit(SubExpr);
895 }
896
897 void VisitExprWithCleanups(const ExprWithCleanups *S) {
898
899
900
901 auto *SubExpr = S->getSubExpr();
902 assert(SubExpr != nullptr);
903 Visit(SubExpr);
904 }
905
906private:
907
908 BoolValue &getLogicOperatorSubExprValue(const Expr &SubExpr) {
909
910
911
912 if (const Environment *SubExprEnv = StmtToEnv.getEnvironment(SubExpr))
913 if (auto *Val =
914 dyn_cast_or_null(SubExprEnv->getValue(SubExpr)))
915 return *Val;
916
917
918
919
920
921
922 if (Env.getValue(SubExpr) == nullptr)
923 Visit(&SubExpr);
924 if (auto *Val = dyn_cast_or_null(Env.getValue(SubExpr)))
925 return *Val;
926
927
928
929 return Env.makeAtomicBoolValue();
930 }
931
932
933
934 template
935 void transferInlineCall(const E *S, const FunctionDecl *F) {
936 const auto &Options = Env.getDataflowAnalysisContext().getOptions();
937 if (!(Options.ContextSensitiveOpts &&
938 Env.canDescend(Options.ContextSensitiveOpts->Depth, F)))
939 return;
940
941 const AdornedCFG *ACFG = Env.getDataflowAnalysisContext().getAdornedCFG(F);
942 if (!ACFG)
943 return;
944
945
946
947
948
949 auto ExitBlock = ACFG->getCFG().getExit().getBlockID();
950
951 auto CalleeEnv = Env.pushCall(S);
952
953
954
955
956 auto Analysis = NoopAnalysis(ACFG->getDecl().getASTContext(),
957 DataflowAnalysisOptions{Options});
958
959 auto BlockToOutputState =
961 assert(BlockToOutputState);
962 assert(ExitBlock < BlockToOutputState->size());
963
964 auto &ExitState = (*BlockToOutputState)[ExitBlock];
965 assert(ExitState);
966
967 Env.popCall(S, ExitState->Env);
968 }
969
970 const StmtToEnvMap &StmtToEnv;
971 Environment &Env;
972 Environment::ValueModel &Model;
973};
974
975}
976
979 TransferVisitor(StmtToEnv, Env, Model).Visit(&S);
980}
981
982}
983}
Defines enum values for all the target-independent builtin functions.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines an enumeration for C++ overloaded operators.
C Language Family Type Representation.
Represents a single basic block in a source-level CFG.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
This represents one expression.
Stmt - This represents one statement.
bool isNullPtrType() const
bool isRecordType() const
BoolValue & makeBoolValue(const Formula &)
Creates a BoolValue wrapping a particular formula.
Supplements Environment with non-standard comparison and join operations.
Holds the state of the program (store and heap) at a given program point.
BoolValue & makeIff(BoolValue &LHS, BoolValue &RHS) const
Returns a boolean value represents LHS <=> RHS.
StorageLocation * getStorageLocation(const ValueDecl &D) const
Returns the storage location assigned to D in the environment, or null if D isn't assigned a storage ...
BoolValue & makeAtomicBoolValue() const
Returns an atomic boolean value.
Value * getValue(const StorageLocation &Loc) const
Returns the value assigned to Loc in the environment or null if Loc isn't assigned a value in the env...
BoolValue & getBoolLiteralValue(bool Value) const
Returns a symbolic boolean value that models a boolean literal equal to Value
DataflowAnalysisContext & getDataflowAnalysisContext() const
Returns the DataflowAnalysisContext used by the environment.
static Value * joinValues(QualType Ty, Value *Val1, const Environment &Env1, Value *Val2, const Environment &Env2, Environment &JoinedEnv, Environment::ValueModel &Model)
Returns a value that approximates both Val1 and Val2, or null if no such value can be produced.
void setStorageLocation(const ValueDecl &D, StorageLocation &Loc)
Assigns Loc as the storage location of D in the environment.
void setValue(const StorageLocation &Loc, Value &Val)
Assigns Val as the value of Loc in the environment.
Maps statements to the environments of basic blocks that contain them.
const Environment * getEnvironment(const Stmt &S) const
Returns the environment of the basic block that contains S.
Definition Transfer.cpp:44
Base class for all values computed by abstract interpretation.
void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, Environment::ValueModel &Model)
Evaluates S and updates Env accordingly.
Definition Transfer.cpp:977
static void propagateValueOrStorageLocation(const Expr &From, const Expr &To, Environment &Env)
Definition Transfer.cpp:134
static void propagateStorageLocation(const Expr &From, const Expr &To, Environment &Env)
Definition Transfer.cpp:125
void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, Environment &Env, QualType TypeToCopy=QualType())
Copies a record (struct, class, or union) from Src to Dst.
static void propagateValue(const Expr &From, const Expr &To, Environment &Env)
Definition Transfer.cpp:118
static Value * maybeUnpackLValueExpr(const Expr &E, Environment &Env)
Definition Transfer.cpp:101
static BoolValue & unpackValue(BoolValue &V, Environment &Env)
Definition Transfer.cpp:90
static BoolValue & evaluateBooleanEquality(const Expr &LHS, const Expr &RHS, Environment &Env)
Definition Transfer.cpp:60
RecordStorageLocation * getBaseObjectLocation(const MemberExpr &ME, const Environment &Env)
Returns the storage location for the base object of a MemberExpr, or null if none is defined in the e...
llvm::Expected< std::vector< std::optional< DataflowAnalysisState< typename AnalysisT::Lattice > > > > runDataflowAnalysis(const AdornedCFG &ACFG, AnalysisT &Analysis, const Environment &InitEnv, CFGEltCallbacks< AnalysisT > PostAnalysisCallbacks={}, std::int32_t MaxBlockVisits=kDefaultMaxBlockVisits)
Performs dataflow analysis and returns a mapping from basic block IDs to dataflow analysis states tha...
bool Ret(InterpState &S, CodePtr &PC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Type
The name was classified as a type.
U cast(CodeGen::Address addr)