30 #include "llvm/ADT/ImmutableList.h"
31 #include "llvm/ADT/Statistic.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Support/SaveAndRestore.h"
36 #include "llvm/Support/GraphWriter.h"
39 using namespace clang;
43 #define DEBUG_TYPE "ExprEngine"
46 "The # of times RemoveDeadBindings is called");
48 "The # of aborted paths due to reaching the maximum block count in "
49 "a top level function");
50 STATISTIC(NumMaxBlockCountReachedInInlined,
51 "The # of aborted paths due to reaching the maximum block count in "
52 "an inlined function");
54 "The # of times we re-evaluated a call without inlining");
56 typedef std::pair<const CXXBindTemporaryExpr *, const StackFrameContext *>
69 static const
char* TagProviderName = "
ExprEngine";
76 AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
79 StateMgr(getContext(), mgr.getStoreManagerCreator(),
80 mgr.getConstraintManagerCreator(), G.getAllocator(),
82 SymMgr(StateMgr.getSymbolManager()),
83 svalBuilder(StateMgr.getSValBuilder()),
84 currStmtIdx(0), currBldrCtx(
nullptr),
85 ObjCNoRet(mgr.getASTContext()),
86 ObjCGCEnabled(gcEnabled), BR(mgr, *this),
87 VisitedCallees(VisitedCalleesIn),
88 HowToInline(HowToInlineIn)
90 unsigned TrimInterval = mgr.options.getGraphTrimInterval();
91 if (TrimInterval != 0) {
93 G.enableNodeReclamation(TrimInterval);
114 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
118 if (!II || !(II->
getName() ==
"main" && FD->getNumParams() > 0))
127 const MemRegion *R = state->getRegion(PD, InitLoc);
153 const MemRegion *R = state->getRegion(SelfD, InitLoc);
158 state = state->assume(*LV,
true);
159 assert(state &&
"'self' cannot be null");
164 if (!MD->isStatic()) {
171 SVal V = state->getSVal(L);
173 state = state->assume(*LV,
true);
174 assert(state &&
"'this' cannot be null");
187 const Expr *Result) {
188 SVal V = State->getSVal(Ex, LC);
212 while (
const CastExpr *CE = dyn_cast<CastExpr>(Inner)) {
213 if (CE->getCastKind() == CK_DerivedToBase ||
214 CE->getCastKind() == CK_UncheckedDerivedToBase)
216 else if (CE->getCastKind() != CK_NoOp)
227 dyn_cast<MaterializeTemporaryExpr>(Result)) {
242 State = State->bindLoc(Reg, V);
251 State = State->BindExpr(Result, LC, Reg);
262 SVal cond,
bool assumption) {
277 Explicits, Regions, Call);
281 const char *NL,
const char *Sep) {
292 currStmtIdx = StmtIdx;
344 const Stmt *ReferenceStmt,
346 const Stmt *DiagnosticStmt,
349 ReferenceStmt ==
nullptr || isa<ReturnStmt>(ReferenceStmt))
350 &&
"PostStmt is not generally supported by the SymbolReaper yet");
351 assert(LC &&
"Must pass the current (or expiring) LocationContext");
353 if (!DiagnosticStmt) {
354 DiagnosticStmt = ReferenceStmt;
355 assert(DiagnosticStmt &&
"Required for clearing a LocationContext");
358 NumRemoveDeadBindings++;
364 if (!ReferenceStmt) {
366 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
388 Bldr.
generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K);
395 DiagnosticStmt, *
this, K);
410 "Checkers are not allowed to modify the Environment as a part of "
411 "checkDeadSymbols processing.");
413 "Checkers are not allowed to modify the Store as a part of "
414 "checkDeadSymbols processing.");
420 Bldr.
generateNode(DiagnosticStmt, *
I, CleanedCheckerSt, &cleanupTag, K);
432 currStmt->getLocStart(),
433 "Error evaluating statement");
440 CleanedStates.Add(Pred);
445 E = CleanedStates.end();
I !=
E; ++
I) {
448 Visit(currStmt, *
I, DstI);
462 "Error evaluating initializer");
468 cast<CXXConstructorDecl>(stackFrame->getDecl());
471 SVal thisVal = State->getSVal(svalBuilder.
getCXXThis(decl, stackFrame));
480 if (
auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) {
492 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
500 while ((ASE = dyn_cast<ArraySubscriptExpr>(Init)))
503 SVal LValue = State->getSVal(Init, stackFrame);
505 InitVal = State->getSVal(*LValueLoc);
515 InitVal = State->getSVal(BMI->
getInit(), stackFrame);
518 assert(Tmp.
size() == 1 &&
"have not generated any new nodes yet");
519 assert(*Tmp.
begin() == Pred &&
"have not generated any new nodes yet");
523 evalBind(Tmp, Init, Pred, FieldLoc, InitVal,
true, &PP);
564 llvm_unreachable(
"Unexpected dtor kind.");
602 Region = state->getSVal(Region).getAsRegion();
616 SVal ArgVal = State->getSVal(Arg, LCtx);
620 if (State->isNull(ArgVal).isConstrainedTrue()) {
628 Bldr.generateNode(PP, Pred->
getState(), Pred);
654 CurDtor->
getBody(),
true, Pred, Dst);
667 State->getLValue(Member, State->getSVal(ThisVal).castAs<
Loc>());
671 CurDtor->
getBody(),
false, Pred, Dst);
680 if (State->contains<InitializedTemporariesSet>(
684 State = State->remove<InitializedTemporariesSet>(
692 assert(CleanDtorState.
size() <= 1);
694 CleanDtorState.
empty() ? Pred : *CleanDtorState.
begin();
698 false, CleanPred, Dst);
708 if (Pred->
getState()->contains<InitializedTemporariesSet>(
731 if (!State->contains<InitializedTemporariesSet>(
732 std::make_pair(BTE,
Node->getStackFrame()))) {
737 State = State->add<InitializedTemporariesSet>(
738 std::make_pair(BTE,
Node->getStackFrame()));
748 "Error evaluating statement");
752 assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
754 switch (S->getStmtClass()) {
756 case Expr::ObjCIndirectCopyRestoreExprClass:
757 case Stmt::CXXDependentScopeMemberExprClass:
758 case Stmt::CXXInheritedCtorInitExprClass:
759 case Stmt::CXXTryStmtClass:
760 case Stmt::CXXTypeidExprClass:
761 case Stmt::CXXUuidofExprClass:
762 case Stmt::CXXFoldExprClass:
763 case Stmt::MSPropertyRefExprClass:
764 case Stmt::MSPropertySubscriptExprClass:
765 case Stmt::CXXUnresolvedConstructExprClass:
766 case Stmt::DependentScopeDeclRefExprClass:
767 case Stmt::ArrayTypeTraitExprClass:
768 case Stmt::ExpressionTraitExprClass:
769 case Stmt::UnresolvedLookupExprClass:
770 case Stmt::UnresolvedMemberExprClass:
771 case Stmt::TypoExprClass:
772 case Stmt::CXXNoexceptExprClass:
773 case Stmt::PackExpansionExprClass:
774 case Stmt::SubstNonTypeTemplateParmPackExprClass:
775 case Stmt::FunctionParmPackExprClass:
776 case Stmt::CoroutineBodyStmtClass:
777 case Stmt::CoawaitExprClass:
778 case Stmt::CoreturnStmtClass:
779 case Stmt::CoyieldExprClass:
780 case Stmt::SEHTryStmtClass:
781 case Stmt::SEHExceptStmtClass:
782 case Stmt::SEHLeaveStmtClass:
783 case Stmt::SEHFinallyStmtClass: {
789 case Stmt::ParenExprClass:
790 llvm_unreachable(
"ParenExprs already handled.");
791 case Stmt::GenericSelectionExprClass:
792 llvm_unreachable(
"GenericSelectionExprs already handled.");
795 case Stmt::BreakStmtClass:
796 case Stmt::CaseStmtClass:
797 case Stmt::CompoundStmtClass:
798 case Stmt::ContinueStmtClass:
799 case Stmt::CXXForRangeStmtClass:
800 case Stmt::DefaultStmtClass:
801 case Stmt::DoStmtClass:
802 case Stmt::ForStmtClass:
803 case Stmt::GotoStmtClass:
804 case Stmt::IfStmtClass:
805 case Stmt::IndirectGotoStmtClass:
806 case Stmt::LabelStmtClass:
807 case Stmt::NoStmtClass:
808 case Stmt::NullStmtClass:
809 case Stmt::SwitchStmtClass:
810 case Stmt::WhileStmtClass:
811 case Expr::MSDependentExistsStmtClass:
812 case Stmt::CapturedStmtClass:
813 case Stmt::OMPParallelDirectiveClass:
814 case Stmt::OMPSimdDirectiveClass:
815 case Stmt::OMPForDirectiveClass:
816 case Stmt::OMPForSimdDirectiveClass:
817 case Stmt::OMPSectionsDirectiveClass:
818 case Stmt::OMPSectionDirectiveClass:
819 case Stmt::OMPSingleDirectiveClass:
820 case Stmt::OMPMasterDirectiveClass:
821 case Stmt::OMPCriticalDirectiveClass:
822 case Stmt::OMPParallelForDirectiveClass:
823 case Stmt::OMPParallelForSimdDirectiveClass:
824 case Stmt::OMPParallelSectionsDirectiveClass:
825 case Stmt::OMPTaskDirectiveClass:
826 case Stmt::OMPTaskyieldDirectiveClass:
827 case Stmt::OMPBarrierDirectiveClass:
828 case Stmt::OMPTaskwaitDirectiveClass:
829 case Stmt::OMPTaskgroupDirectiveClass:
830 case Stmt::OMPFlushDirectiveClass:
831 case Stmt::OMPOrderedDirectiveClass:
832 case Stmt::OMPAtomicDirectiveClass:
833 case Stmt::OMPTargetDirectiveClass:
834 case Stmt::OMPTargetDataDirectiveClass:
835 case Stmt::OMPTargetEnterDataDirectiveClass:
836 case Stmt::OMPTargetExitDataDirectiveClass:
837 case Stmt::OMPTargetParallelDirectiveClass:
838 case Stmt::OMPTargetParallelForDirectiveClass:
839 case Stmt::OMPTargetUpdateDirectiveClass:
840 case Stmt::OMPTeamsDirectiveClass:
841 case Stmt::OMPCancellationPointDirectiveClass:
842 case Stmt::OMPCancelDirectiveClass:
843 case Stmt::OMPTaskLoopDirectiveClass:
844 case Stmt::OMPTaskLoopSimdDirectiveClass:
845 case Stmt::OMPDistributeDirectiveClass:
846 case Stmt::OMPDistributeParallelForDirectiveClass:
847 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
848 case Stmt::OMPDistributeSimdDirectiveClass:
849 case Stmt::OMPTargetParallelForSimdDirectiveClass:
850 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
852 case Stmt::ObjCSubscriptRefExprClass:
853 case Stmt::ObjCPropertyRefExprClass:
854 llvm_unreachable(
"These are handled by PseudoObjectExpr");
856 case Stmt::GNUNullExprClass: {
865 case Stmt::ObjCAtSynchronizedStmtClass:
871 case Stmt::ExprWithCleanupsClass:
875 case Stmt::CXXBindTemporaryExprClass: {
887 case Stmt::DesignatedInitExprClass:
888 case Stmt::DesignatedInitUpdateExprClass:
889 case Stmt::ExtVectorElementExprClass:
890 case Stmt::ImaginaryLiteralClass:
891 case Stmt::ObjCAtCatchStmtClass:
892 case Stmt::ObjCAtFinallyStmtClass:
893 case Stmt::ObjCAtTryStmtClass:
894 case Stmt::ObjCAutoreleasePoolStmtClass:
895 case Stmt::ObjCEncodeExprClass:
896 case Stmt::ObjCIsaExprClass:
897 case Stmt::ObjCProtocolExprClass:
898 case Stmt::ObjCSelectorExprClass:
899 case Stmt::ParenListExprClass:
900 case Stmt::ShuffleVectorExprClass:
901 case Stmt::ConvertVectorExprClass:
902 case Stmt::VAArgExprClass:
903 case Stmt::CUDAKernelCallExprClass:
904 case Stmt::OpaqueValueExprClass:
905 case Stmt::AsTypeExprClass:
910 case Stmt::PredefinedExprClass:
911 case Stmt::AddrLabelExprClass:
912 case Stmt::AttributedStmtClass:
913 case Stmt::IntegerLiteralClass:
914 case Stmt::CharacterLiteralClass:
915 case Stmt::ImplicitValueInitExprClass:
916 case Stmt::CXXScalarValueInitExprClass:
917 case Stmt::CXXBoolLiteralExprClass:
918 case Stmt::ObjCBoolLiteralExprClass:
919 case Stmt::ObjCAvailabilityCheckExprClass:
920 case Stmt::FloatingLiteralClass:
921 case Stmt::NoInitExprClass:
922 case Stmt::SizeOfPackExprClass:
923 case Stmt::StringLiteralClass:
924 case Stmt::ObjCStringLiteralClass:
925 case Stmt::CXXPseudoDestructorExprClass:
926 case Stmt::SubstNonTypeTemplateParmExprClass:
927 case Stmt::CXXNullPtrLiteralExprClass:
928 case Stmt::OMPArraySectionExprClass:
929 case Stmt::TypeTraitExprClass: {
938 case Stmt::CXXDefaultArgExprClass:
939 case Stmt::CXXDefaultInitExprClass: {
949 ArgE = DefE->getExpr();
951 ArgE = DefE->getExpr();
953 llvm_unreachable(
"unknown constant wrapper kind");
955 bool IsTemporary =
false;
957 dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
958 ArgE = MTE->GetTemporaryExpr();
970 State = State->BindExpr(S, LCtx, *ConstantVal);
972 State = createTemporaryRegionIfNeeded(State, LCtx,
984 case Stmt::CXXStdInitializerListExprClass:
985 case Expr::ObjCArrayLiteralClass:
986 case Expr::ObjCDictionaryLiteralClass:
987 case Expr::ObjCBoxedExprClass: {
996 const Expr *Ex = cast<Expr>(
S);
1015 case Stmt::ArraySubscriptExprClass:
1021 case Stmt::GCCAsmStmtClass:
1027 case Stmt::MSAsmStmtClass:
1033 case Stmt::BlockExprClass:
1039 case Stmt::LambdaExprClass:
1050 case Stmt::BinaryOperatorClass: {
1062 state->getSVal(B->
getRHS(),
1082 case Stmt::CXXOperatorCallExprClass: {
1088 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
1089 if (MD->isInstance()) {
1093 createTemporaryRegionIfNeeded(State, LCtx, OCE->
getArg(0));
1094 if (NewState != State) {
1105 case Stmt::CallExprClass:
1106 case Stmt::CXXMemberCallExprClass:
1107 case Stmt::UserDefinedLiteralClass: {
1114 case Stmt::CXXCatchStmtClass: {
1121 case Stmt::CXXTemporaryObjectExprClass:
1122 case Stmt::CXXConstructExprClass: {
1129 case Stmt::CXXNewExprClass: {
1138 case Stmt::CXXDeleteExprClass: {
1145 e = PreVisit.
end(); i != e ; ++i)
1154 case Stmt::ChooseExprClass: {
1162 case Stmt::CompoundAssignOperatorClass:
1168 case Stmt::CompoundLiteralExprClass:
1174 case Stmt::BinaryConditionalOperatorClass:
1175 case Stmt::ConditionalOperatorClass: {
1178 = cast<AbstractConditionalOperator>(
S);
1184 case Stmt::CXXThisExprClass:
1190 case Stmt::DeclRefExprClass: {
1198 case Stmt::DeclStmtClass:
1204 case Stmt::ImplicitCastExprClass:
1205 case Stmt::CStyleCastExprClass:
1206 case Stmt::CXXStaticCastExprClass:
1207 case Stmt::CXXDynamicCastExprClass:
1208 case Stmt::CXXReinterpretCastExprClass:
1209 case Stmt::CXXConstCastExprClass:
1210 case Stmt::CXXFunctionalCastExprClass:
1211 case Stmt::ObjCBridgedCastExprClass: {
1221 e = dstPrevisit.end(); i != e ; ++i) {
1231 case Expr::MaterializeTemporaryExprClass: {
1239 case Stmt::InitListExprClass:
1245 case Stmt::MemberExprClass:
1251 case Stmt::AtomicExprClass:
1257 case Stmt::ObjCIvarRefExprClass:
1263 case Stmt::ObjCForCollectionStmtClass:
1269 case Stmt::ObjCMessageExprClass:
1275 case Stmt::ObjCAtThrowStmtClass:
1276 case Stmt::CXXThrowExprClass:
1282 case Stmt::ReturnStmtClass:
1288 case Stmt::OffsetOfExprClass:
1294 case Stmt::UnaryExprOrTypeTraitExprClass:
1301 case Stmt::StmtExprClass: {
1307 &&
"Empty statement expression must have void type.");
1315 state->getSVal(LastExpr,
1321 case Stmt::UnaryOperatorClass: {
1335 case Stmt::PseudoObjectExprClass: {
1355 bool ExprEngine::replayWithoutInlining(
ExplodedNode *N,
1359 assert(CalleeSF && CallerSF);
1366 BeforeProcessingCall = N;
1381 if (SP->getStmt() == CE)
1386 if (!BeforeProcessingCall)
1414 NumTimesRetriedWithoutInlining++;
1431 (isa<ForStmt>(Term) || isa<WhileStmt>(Term) || isa<DoStmt>(Term))))
1452 (*G.
roots_begin())->getLocation().getLocationContext();
1461 replayWithoutInlining(Pred, CalleeLC)))
1463 NumMaxBlockCountReachedInInlined++;
1465 NumMaxBlockCountReached++;
1468 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
1483 const Stmt *Condition,
1487 const Expr *Ex = dyn_cast<
Expr>(Condition);
1492 bool bitsInit =
false;
1494 while (
const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
1501 if (!bitsInit || newBits < bits) {
1506 Ex = CE->getSubExpr();
1516 return state->getSVal(Ex, LCtx);
1548 if (
const Expr *Ex = dyn_cast<Expr>(Condition))
1556 "Temporary destructor branches handled by processBindTemporary.");
1567 for (; I !=
E; ++
I) {
1572 const Stmt *LastStmt = CS->getStmt();
1576 llvm_unreachable(
"could not resolve condition");
1585 assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) &&
1586 "CXXBindTemporaryExprs are handled by processBindTemporary.");
1589 currBldrCtx = &BldCtx;
1599 if (
const Expr *Ex = dyn_cast<Expr>(Condition))
1604 Condition->getLocStart(),
1605 "Error evaluating branch");
1611 if (CheckersOutSet.empty())
1616 E = CheckersOutSet.end();
E !=
I; ++
I) {
1627 if (
const Expr *Ex = dyn_cast<Expr>(Condition)) {
1634 PrevState, Condition,
1655 std::tie(StTrue, StFalse) = PrevState->assume(V);
1673 currBldrCtx =
nullptr;
1688 currBldrCtx = &BuilderCtx;
1690 const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
1692 bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
1696 state = state->add<InitializedGlobalsSet>(VD);
1699 builder.generateNode(state, initHasRun, Pred);
1700 builder.markInfeasible(!initHasRun);
1702 currBldrCtx =
nullptr;
1724 for (iterator
I = builder.
begin(),
E = builder.
end();
I !=
E; ++
I) {
1725 if (
I.getLabel() == L) {
1731 llvm_unreachable(
"No block with label.");
1745 for (iterator
I=builder.
begin(),
E=builder.
end();
I !=
E; ++
I)
1750 static bool stackFrameDoesNotContainInitializedTemporaries(
ExplodedNode &Pred) {
1753 Pred.
getState()->get<InitializedTemporariesSet>();
1754 return std::find_if(Set.begin(), Set.end(),
1756 if (Ctx.second == Frame) {
1758 llvm::errs() <<
"\n";
1760 return Ctx.second == Frame;
1791 E = AfterRemovedDead.
end();
I !=
E; ++
I) {
1809 if (CondV_untested.
isUndef()) {
1820 iterator
I = builder.
begin(), EI = builder.
end();
1821 bool defaultIsFeasible = I == EI;
1823 for ( ; I != EI; ++
I) {
1828 const CaseStmt *Case = I.getCase();
1843 std::tie(StateCase, DefaultSt) =
1844 DefaultSt->assumeWithinInclusiveRange(*NL, V1, V2);
1846 StateCase = DefaultSt;
1854 defaultIsFeasible =
true;
1856 defaultIsFeasible =
false;
1861 if (!defaultIsFeasible)
1893 if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1896 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
1898 const Decl *D = LocCtxt->getDecl();
1900 const auto *DeclRefEx = dyn_cast<
DeclRefExpr>(Ex);
1904 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
1905 MD->getParent()->isLambda()) {
1908 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
1911 const FieldDecl *FD = LambdaCaptureFields[VD];
1915 assert(VD->getType().isConstQualified());
1916 V = state->getLValue(VD, LocCtxt);
1917 IsReference =
false;
1920 svalBuilder.
getCXXThis(MD, LocCtxt->getCurrentStackFrame());
1921 SVal CXXThisVal = state->getSVal(CXXThis);
1922 V = state->getLValue(FD, CXXThisVal);
1926 V = state->getLValue(VD, LocCtxt);
1927 IsReference = VD->getType()->isReferenceType();
1933 if (
const MemRegion *R = V.getAsRegion())
1934 V = state->getSVal(R);
1939 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
1946 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
1949 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1951 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
1955 if (isa<FieldDecl>(D)) {
1962 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
1967 llvm_unreachable(
"Support for this Decl not implemented.");
1987 ei = checkerPreStmt.
end(); it != ei; ++it) {
1991 state->getSVal(Idx, LCtx),
1992 state->getSVal(Base, LCtx));
1993 Bldr.
generateNode(A, *it, state->BindExpr(A, LCtx, V),
nullptr,
2011 if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
2028 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
2029 if (MD->isInstance())
2030 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2033 state = state->BindExpr(M, LCtx, MDVal);
2040 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2041 SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
2043 FieldDecl *field = cast<FieldDecl>(Member);
2044 SVal L = state->getLValue(field, baseExprVal);
2055 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
2056 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
2061 if (
const MemRegion *R = L.getAsRegion())
2062 L = state->getSVal(R);
2067 Bldr.
generateNode(M, *
I, state->BindExpr(M, LCtx, L),
nullptr,
2099 SVal SubExprVal = State->getSVal(SubExpr, LCtx);
2100 ValuesToInvalidate.push_back(SubExprVal);
2103 State = State->invalidateRegions(ValuesToInvalidate, AE,
2110 State = State->BindExpr(AE, LCtx, ResultVal);
2119 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
2126 bool VisitSymbol(
SymbolRef Sym)
override {
2127 Symbols.insert(Sym);
2141 bool escapes =
true;
2145 escapes = !regionLoc->getRegion()->hasStackStorage();
2153 SVal StoredVal = State->getSVal(regionLoc->getRegion());
2154 if (StoredVal != Val)
2155 escapes = (State == (State->bindLoc(*regionLoc, Val)));
2167 CollectReachableSymbolsCallback Scanner =
2168 State->scanReachableSymbols<CollectReachableSymbolsCallback>(Val);
2187 if (!Invalidated || Invalidated->empty())
2201 E = ExplicitRegions.end();
I !=
E; ++
I) {
2203 SymbolsDirectlyInvalidated.insert(R->getSymbol());
2207 for (InvalidatedSymbols::const_iterator
I=Invalidated->begin(),
2208 E = Invalidated->end();
I!=
E; ++
I) {
2210 if (SymbolsDirectlyInvalidated.count(sym))
2212 SymbolsIndirectlyInvalidated.insert(sym);
2215 if (!SymbolsDirectlyInvalidated.empty())
2220 if (!SymbolsIndirectlyInvalidated.empty())
2242 StoreE, *
this, *PP);
2267 state = state->bindLoc(location.
castAs<
Loc>(),
2273 LocReg = LocRegVal->getRegion();
2290 const Expr *LocationE,
2296 const Expr *StoreE = AssignE ? AssignE : LocationE;
2300 evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag,
false);
2309 evalBind(Dst, StoreE, *NI, location, Val,
false);
2314 const Expr *BoundEx,
2321 assert(!location.
getAs<
NonLoc>() &&
"location cannot be a NonLoc.");
2327 dyn_cast_or_null<TypedValueRegion>(location.
getAsRegion())) {
2332 loadReferenceTag(TagProviderName,
"Load Reference");
2334 evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state,
2335 location, &loadReferenceTag,
2336 getContext().getPointerType(RT->getPointeeType()));
2340 state = (*I)->getState();
2341 location = state->getSVal(BoundEx, (*I)->getLocationContext());
2342 evalLoadCommon(Dst, NodeEx, BoundEx, *
I, state, location, tag, LoadTy);
2348 evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy);
2353 const Expr *BoundEx,
2363 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag,
true);
2373 state = (*NI)->getState();
2380 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
2383 Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag,
2390 const Stmt *BoundEx,
2403 BldrTop.takeNodes(Pred);
2416 Bldr.generateNode(NodeEx, Pred, state, &tag);
2420 NodeEx, BoundEx, *
this);
2421 BldrTop.addNodes(Tmp);
2424 std::pair<const ProgramPointTag *, const ProgramPointTag*>
2427 eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
2428 "Eagerly Assume True"),
2429 eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
2430 "Eagerly Assume False");
2431 return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
2432 &eagerlyAssumeBinOpBifurcationFalse);
2453 if (SEV && SEV->isExpression()) {
2454 const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
2458 std::tie(StateTrue, StateFalse) = state->assume(*SEV);
2536 return "color=\"red\",style=\"filled\"";
2539 return "color=\"blue\",style=\"filled\"";
2557 llvm::raw_string_ostream Out(sbuf);
2564 Out <<
"Block Entrance: B"
2584 Out <<
"CallExitBegin";
2588 Out <<
"CallExitEnd";
2592 Out <<
"PostStmtPurgeDeadSymbols";
2596 Out <<
"PreStmtPurgeDeadSymbols";
2600 Out <<
"Epsilon Point";
2615 Out <<
"PostCall: ";
2624 Out <<
"PostInitializer: ";
2646 Out <<
"\\|Terminator: ";
2657 if (isa<SwitchStmt>(T)) {
2661 if (
const CaseStmt *
C = dyn_cast<CaseStmt>(Label)) {
2667 if (
const Stmt *RHS =
C->getRHS()) {
2675 assert (isa<DefaultStmt>(Label));
2676 Out <<
"\\ldefault:";
2680 Out <<
"\\l(implicit) default:";
2682 else if (isa<IndirectGotoStmt>(T)) {
2686 Out <<
"\\lCondition: ";
2700 Out <<
"\\|Control-flow based on\\lUndefined value.\\l";
2708 assert(S !=
nullptr &&
"Expecting non-null Stmt");
2710 Out << S->getStmtClassName() <<
' ' << (
const void*) S <<
' ';
2713 printLocation(Out, S->getLocStart());
2716 Out <<
"\\lPreStmt\\l;";
2718 Out <<
"\\lPostLoad\\l;";
2720 Out <<
"\\lPostStore\\l";
2722 Out <<
"\\lPostLValue\\l";
2728 Out <<
"\\|Implicit-Null Dereference.\\l";
2730 Out <<
"\\|Explicit-Null Dereference.\\l";
2732 Out <<
"\\|Dereference of undefialied value.\\l";
2734 Out <<
"\\|Store to Undefined Loc.";
2736 Out <<
"\\|Result of operation is undefined.";
2738 Out <<
"\\|Call to function marked \"noreturn\".";
2740 Out <<
"\\|Call to NULL/Undefined.";
2742 Out <<
"\\|Argument in call is undefined";
2750 Out <<
"\\|StateID: " << (
const void*) state.get()
2751 <<
" NodeID: " << (
const void*) N <<
"\\|";
2752 state->printDOT(Out);
2769 std::vector<const ExplodedNode*> Src;
2774 const_cast<BugType*>(*I)->FlushReports(BR);
2780 if (N) Src.push_back(N);
2802 std::unique_ptr<ExplodedGraph> TrimmedG(G.
trim(Nodes));
2804 if (!TrimmedG.get())
2805 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
2807 llvm::ViewGraph(*TrimmedG->roots_begin(),
"TrimmedExprEngine");
A call to an overloaded operator written using operator syntax.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
unsigned getNumArrayIndices() const
Determine the number of implicit array indices used while described an array member initialization...
CFGNewAllocator - Represents C++ allocator call.
This represents a GCC inline-assembly statement extension.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
TypedValueRegion - An abstract class representing regions having a typed value.
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred)
STATISTIC(NumRemoveDeadBindings,"The # of times RemoveDeadBindings is called")
ProgramStateRef getState() const
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
const CXXNewExpr * getAllocatorExpr() const
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
void markInfeasible(bool branch)
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool hasDeadSymbols() const
bool isMemberPointerType() const
QualType getType() const
Retrieves the type of the base class.
succ_iterator succ_begin()
CompoundStmt * getSubStmt()
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
Information about invalidation for a particular region/symbol.
const Expr * getCondition() const
This builder class is useful for generating nodes that resulted from visiting a statement.
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, ExplodedNodeSet &PreVisit, ExplodedNodeSet &Dst)
EnumConstantDecl - An instance of this object exists for each enum constant that is defined...
bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2)
Defines the SourceManager interface.
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
const LocationContext * getLocationContext() const
static const Stmt * getRightmostLeaf(const Stmt *Condition)
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMSAsmStmt - Transfer function logic for MS inline asm.
virtual QualType getValueType() const =0
Represents a point when we begin processing an inlined call.
SourceLocation getLocStart() const LLVM_READONLY
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
void runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on end of function.
void printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) override
printState - Called by ProgramStateManager to print checker-specific data.
const RegionTy * getAs() const
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T)
static ExprEngine * GraphPrintCheckerState
The pointer has been passed to a function indirectly.
void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, NodeBuilderContext &BldCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
Called by CoreEngine.
CFGDeleteDtor - Represents C++ object destructor generated from a call to delete. ...
Represents a program point just before an implicit call event.
const CXXDeleteExpr * getDeleteExpr() const
void ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
static std::string getNodeLabel(const ExplodedNode *N, void *)
bool isCForbiddenLValueType() const
Determine whether expressions of the given type are forbidden from being lvalues in C...
bool shouldWidenLoops()
Returns true if the analysis should try to widen loops.
Represents a C++ constructor within a class.
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
void processCFGBlockEntrance(const BlockEdge &L, NodeBuilderWithSinks &nodeBuilder, ExplodedNode *Pred) override
Called by CoreEngine when processing the entrance of a CFGBlock.
bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2)
const FieldDecl * getFieldDecl() const
ProgramStateRef getInitialState(const LocationContext *InitLoc) override
getInitialState - Return the initial state used for the root vertex in the ExplodedGraph.
Represents an implicit call event.
ImplTy::const_iterator const_iterator
void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryOperator - Transfer function logic for unary operators.
void takeNodes(const ExplodedNodeSet &S)
VarDecl - An instance of this class is created to represent a variable declaration or definition...
void markReachedMaxBlockCount(const Decl *D)
Expr * getInit() const
Get the initializer.
void printTerminator(raw_ostream &OS, const LangOptions &LO) const
printTerminator - A simple pretty printer of the terminator of a CFGBlock.
void ProcessDeleteDtor(const CFGDeleteDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ObjCMethodDecl - Represents an instance or class method declaration.
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, const ProgramPointTag *tag=nullptr)
evalStore - Handle the semantics of a store via an assignment.
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
roots_iterator roots_begin()
Describes how types, statements, expressions, and declarations should be printed. ...
Defines the Objective-C statement AST node classes.
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const LocationContext *LC, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer's garbage collection - remove dead symbols and bindings from the state...
ProgramStateRef removeDeadBindings(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
ParmVarDecl - Represents a parameter to a function.
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
BoundNodesTreeBuilder Nodes
void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
const Expr * getTarget() const
void runCheckersForLocation(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, bool isLoad, const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &Eng)
Run checkers for load/store of a location.
const SwitchStmt * getSwitch() const
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
One of these records is kept for each identifier that is lexed.
ImplTy::iterator iterator
A pointer escapes due to binding its value to a location that the analyzer cannot track...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
bool isReferenceType() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Represents a program point after a store evaluation.
CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated for automatic object or t...
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst)
MemRegionManager & getRegionManager()
AnalysisDeclContext * getAnalysisDeclContext() const
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred)
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void EndPath(ProgramStateRef St)
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
unsigned eagerlyAssumeBinOpBifurcation
The flag regulates if we should eagerly assume evaluations of conditionals, thus, bifurcating the pat...
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
static std::string getNodeAttributes(const ExplodedNode *N, void *)
static bool isRelationalOp(Opcode Opc)
static bool isLocType(QualType T)
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
void processEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred) override
Called by CoreEngine.
ExplodedNodeSet::iterator iterator
This is a meta program point, which should be skipped by all the diagnostic reasoning etc...
static bool isEqualityOp(Opcode Opc)
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Expr * getTrueExpr() const
IndirectFieldDecl * getIndirectMember() const
unsigned getIndex() const
const VarDecl * getVarDecl() const
const CFGBlock * getCallSiteBlock() const
ExplodedNode * generateCaseStmtNode(const iterator &I, ProgramStateRef State)
bool isUnknownOrUndef() const
A builtin binary operation expression such as "x + y" or "x <= y".
const Stmt * getCallSite() const
llvm::FoldingSet< BugReportEquivClass >::iterator EQClasses_iterator
Iterator over the set of BugReports tracked by the BugReporter.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
bool wantsRegionChangeUpdate(ProgramStateRef state)
True if at least one checker wants to check region changes.
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
DefinedSVal getFunctionPointer(const FunctionDecl *func)
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
bool isDelegatingInitializer() const
Determine whether this initializer is creating a delegating constructor.
void ProcessStmt(const CFGStmt S, ExplodedNode *Pred)
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
NonLoc makeIntValWithPtrWidth(uint64_t integer, bool isUnsigned)
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents binding an expression to a temporary.
ProgramStateRef getState() const
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
detail::InMemoryDirectory::const_iterator I
const Stmt * getTriggerStmt() const
A default argument (C++ [dcl.fct.default]).
void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, SVal location, SVal Val, bool atDeclInit=false, const ProgramPoint *PP=nullptr)
evalBind - Handle the semantics of binding a value to a specific location.
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
const LocationContext * getLocationContext() const
const CFGBlock * getSrc() const
void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep)
Run checkers for debug-printing a ProgramState.
void removeDeadOnEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
void runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, ExprEngine &Eng, const ProgramPoint &PP)
Run checkers for binding of a value to a location.
static SourceManager * GraphPrintSourceManager
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
CFGBlock - Represents a single basic block in a source-level CFG.
void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path...
const MemRegion * StripCasts(bool StripBaseCasts=true) const
CheckerManager & getCheckerManager() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
InliningModes
The modes of inlining, which override the default analysis-wide settings.
SymbolicRegion - A special, "non-concrete" region.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
static unsigned getNumSubExprs(AtomicOp Op)
Determine the number of arguments the specified atomic builtin should have.
const CFGBlock * getDst() const
void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
void processSwitch(SwitchNodeBuilder &builder) override
ProcessSwitch - Called by CoreEngine.
void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L) override
Called by CoreEngine.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
const ProgramStateRef & getState() const
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
StringRef getName() const
Return the actual identifier string.
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
const Stmt * getStmt() const
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
Represents a C++ destructor within a class.
This is the simplest builder which generates nodes in the ExplodedGraph.
CXXCtorInitializer * getInitializer() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
The pointer has been passed to a function call directly.
std::pair< const CXXBindTemporaryExpr *, const StackFrameContext * > CXXBindTemporaryContext
virtual StringRef getTagDescription() const =0
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
void FlushReports()
Generate and flush diagnostics for all bug reports.
std::pair< const ProgramPointTag *, const ProgramPointTag * > geteagerlyAssumeBinOpBifurcationTags()
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
The reason for pointer escape is unknown.
bool isIndirectMemberInitializer() const
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
Traits for storing the call processing policy inside GDM.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
const LocationContext * getLocationContext() const
unsigned getBlockID() const
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for builtin atomic expressions.
This represents a Microsoft inline-assembly statement extension.
StoreManager & getStoreManager()
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
ExplodedNode * getNode(const ProgramPoint &L, ProgramStateRef State, bool IsSink=false, bool *IsNew=nullptr)
Retrieve the node associated with a (Location,State) pair, where the 'Location' is a ProgramPoint in ...
void evalLoad(ExplodedNodeSet &Dst, const Expr *NodeEx, const Expr *BoundExpr, ExplodedNode *Pred, ProgramStateRef St, SVal location, const ProgramPointTag *tag=nullptr, QualType LoadTy=QualType())
Simulate a read of the result of Ex.
CFGBaseDtor - Represents C++ object destructor implicitly generated for base object in destructor...
QualType getConditionType() const
reverse_iterator rbegin()
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper &SymReaper)=0
ExplodedNode * generateNode(const iterator &I, ProgramStateRef State, bool isSink=false)
While alive, includes the current analysis stack in a crash trace.
void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArraySubscriptExpr - Transfer function for array accesses.
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
static const Stmt * ResolveCondition(const Stmt *Condition, const CFGBlock *B)
void enqueueEndOfFunction(ExplodedNodeSet &Set)
enqueue the nodes corresponding to the end of function onto the end of path / work list...
bool isConsumedExpr(Expr *E) const
CFGTerminator getTerminator()
bool wantsRegionChangeUpdate(ProgramStateRef state) override
wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a region change should trigge...
void processCFGElement(const CFGElement E, ExplodedNode *Pred, unsigned StmtIdx, NodeBuilderContext *Ctx) override
processCFGElement - Called by CoreEngine.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
ProgramStateRef getInitialState(const LocationContext *InitLoc)
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) override
Call PointerEscape callback when a value escapes as a result of bind.
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
EQClasses_iterator EQClasses_begin()
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState, const LocationContext *LCtx, unsigned BlockCount, const Stmt *LoopStmt)
Get the states that result from widening the loop.
Encodes a location in the source.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
const TemplateArgument * iterator
const StackFrameContext * getCurrentStackFrame() const
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
FieldDecl * getAnyMember() const
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
AnalysisManager & getAnalysisManager() override
void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex)
evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic expressions of ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
LabelDecl - Represents the declaration of a label.
ExplodedNode * generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
const Expr * getCond() const
bool isTemporaryDtorsBranch() const
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
static void printLocation(raw_ostream &Out, SourceLocation SLoc)
void processIndirectGoto(IndirectGotoNodeBuilder &builder) override
processIndirectGoto - Called by CoreEngine.
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
SourceLocation getLocStart() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
BugTypesTy::iterator iterator
Iterator over the set of BugTypes tracked by the BugReporter.
const Stmt * getStmt() const
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
void processBranch(const Stmt *Condition, const Stmt *Term, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
ProcessBranch - Called by CoreEngine.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>.
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
AnalyzerOptions & options
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitObjCForCollectionStmt - Transfer function logic for ObjCForCollectionStmt.
const Decl * getDecl() const
A class responsible for cleaning up unused symbols.
bool isAllEnumCasesCovered() const
Returns true if the SwitchStmt is a switch of an enum value and all cases have been explicitly covere...
void getCaptureFields(llvm::DenseMap< const VarDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
static bool isLogicalOp(Opcode Opc)
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
QualType getType() const
Return the type wrapped by this type source info.
void insert(const ExplodedNodeSet &S)
unsigned maxBlockVisitOnPath
The maximum number of times the analyzer visits a block.
std::unique_ptr< ExplodedGraph > trim(ArrayRef< const NodeTy * > Nodes, InterExplodedGraphMap *ForwardMap=nullptr, InterExplodedGraphMap *InverseMap=nullptr) const
Creates a trimmed version of the graph that only contains paths leading to the given nodes...
ast_type_traits::DynTypedNode Node
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
TypeSourceInfo * getTypeSourceInfo() const
Returns the declarator information for a base class or delegating initializer.
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
const LocationContext * getParent() const
ExplodedNode * generateDefaultCaseNode(ProgramStateRef State, bool isSink=false)
SValBuilder & getSValBuilder()
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
void addNodes(const ExplodedNodeSet &S)
StoreManager & getStoreManager()
Represents a program point just after an implicit call event.
const LocationContext * getLocationContext() const
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
const NodeBuilderContext & getContext()
This node builder keeps track of the generated sink nodes.
bool isPurgeKind()
Is this a program point corresponding to purge/removal of dead symbols and bindings.
void reclaimRecentlyAllocatedNodes()
Reclaim "uninteresting" nodes created since the last time this method was called. ...
SourceLocation getLocation() const
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
Represents symbolic expression.
ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits) override
Call PointerEscape callback when a value escapes as a result of region invalidation.
DOTGraphTraits(bool isSimple=false)
detail::InMemoryDirectory::const_iterator E
const MemRegion * getAsRegion() const
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
Represents an abstract call to a function or method along a particular path.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
ProgramStateManager & getStateManager() override
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
const CXXTempObjectRegion * getCXXStaticTempObjectRegion(const Expr *Ex)
Create a CXXTempObjectRegion for temporaries which are lifetime-extended by static references...
SwitchStmt - This represents a 'switch' stmt.
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
const Decl * getDecl() const
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)
Run checkers for end of analysis.
FunctionDecl * getOperatorNew() const
const T * getAs() const
Member-template getAs<specific type>'.
Expr * getFalseExpr() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Represents a C++ base or member initializer.
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for ObjCAtSynchronizedStmts.
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
EQClasses_iterator EQClasses_end()
Base for LValueReferenceType and RValueReferenceType.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Represents a base class of a C++ class.
bool isAnyMemberInitializer() const
SourceManager & getSourceManager()
void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block)
Inform the CoreEngine that a basic block was aborted because it could not be completely analyzed...
const StackFrameContext * getStackFrame() const
A use of a default initializer in a constructor or in aggregate initialization.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedTemporariesSet, llvm::ImmutableSet< CXXBindTemporaryContext >) static const char *TagProviderName
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
const ProgramPointTag * getTag() const
unsigned NoRetryExhausted
Do not re-analyze paths leading to exhausted nodes with a different strategy.
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const CallEvent *Call)
Run checkers for region changes.
Represents a C++ struct/union/class.
reverse_body_iterator body_rbegin()
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
CFGImplicitDtor - Represents C++ object destructor implicitly generated by compiler on various occasi...
Optional< SVal > getConstantVal(const Expr *E)
Returns the value of E, if it can be determined in a non-path-sensitive manner.
pred_iterator pred_begin()
ExplodedNode * generateNode(ProgramStateRef State, bool branch, ExplodedNode *Pred)
CFGElement - Represents a top-level expression in a basic block.
This class is used for builtin types like 'int'.
ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption) override
evalAssume - Callback function invoked by the ConstraintManager when making assumptions about state v...
CFGMemberDtor - Represents C++ object destructor implicitly generated for member object in destructor...
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
void processEndWorklist(bool hasWorkRemaining) override
Called by CoreEngine when the analysis worklist has terminated.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on begining of function.
void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
const LangOptions & getLangOpts() const
A reference to a declared variable, function, enum, etc.
static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const CFGStmt S, const ExplodedNode *Pred, const LocationContext *LC)
CFGInitializer - Represents C++ base or member initializer from constructor's initialization list...
const Expr * getSubExpr() const
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
bool mayInlineCXXAllocator()
Returns whether or not allocator call may be considered for inlining.
void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for member expressions.
ParentMap & getParentMap()
AnalysisPurgeMode AnalysisPurgeOpt
NamedDecl - This represents a decl with a name.
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
ConstraintManager & getConstraintManager()
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
const CXXBaseSpecifier * getBaseSpecifier() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool isFeasible(bool branch)
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
static SVal RecoverCastedSymbol(ProgramStateManager &StateMgr, ProgramStateRef state, const Stmt *Condition, const LocationContext *LCtx, ASTContext &Ctx)
RecoverCastedSymbol - A helper function for ProcessBranch that is used to try to recover some path-se...
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
const MemRegion * getRegion() const
Get the underlining region.
bool shouldInlineLambdas()
Returns true if lambdas should be inlined.
This class handles loading and caching of source files into memory.
CFGTemporaryDtor - Represents C++ object destructor implicitly generated at the end of full expressio...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
Defines enum values for all the target-independent builtin functions.
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const CallEvent *Call) override
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store...