30 #include "llvm/ADT/ImmutableList.h"
31 #include "llvm/ADT/Statistic.h"
32 #include "llvm/Support/raw_ostream.h"
35 #include "llvm/Support/GraphWriter.h"
38 using namespace clang;
42 #define DEBUG_TYPE "ExprEngine"
45 "The # of times RemoveDeadBindings is called");
47 "The # of aborted paths due to reaching the maximum block count in "
48 "a top level function");
49 STATISTIC(NumMaxBlockCountReachedInInlined,
50 "The # of aborted paths due to reaching the maximum block count in "
51 "an inlined function");
53 "The # of times we re-evaluated a call without inlining");
55 typedef std::pair<const CXXBindTemporaryExpr *, const StackFrameContext *>
68 static const
char* TagProviderName = "
ExprEngine";
75 AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
78 StateMgr(getContext(), mgr.getStoreManagerCreator(),
79 mgr.getConstraintManagerCreator(), G.getAllocator(),
81 SymMgr(StateMgr.getSymbolManager()),
82 svalBuilder(StateMgr.getSValBuilder()),
83 currStmtIdx(0), currBldrCtx(
nullptr),
84 ObjCNoRet(mgr.getASTContext()),
85 ObjCGCEnabled(gcEnabled), BR(mgr, *this),
86 VisitedCallees(VisitedCalleesIn),
87 HowToInline(HowToInlineIn)
89 unsigned TrimInterval = mgr.options.getGraphTrimInterval();
90 if (TrimInterval != 0) {
92 G.enableNodeReclamation(TrimInterval);
113 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
117 if (!II || !(II->
getName() ==
"main" && FD->getNumParams() > 0))
126 const MemRegion *R = state->getRegion(PD, InitLoc);
152 const MemRegion *R = state->getRegion(SelfD, InitLoc);
157 state = state->assume(*LV,
true);
158 assert(state &&
"'self' cannot be null");
163 if (!MD->isStatic()) {
170 SVal V = state->getSVal(L);
172 state = state->assume(*LV,
true);
173 assert(state &&
"'this' cannot be null");
186 const Expr *Result) {
187 SVal V = State->getSVal(Ex, LC);
211 while (
const CastExpr *CE = dyn_cast<CastExpr>(Inner)) {
215 else if (CE->getCastKind() !=
CK_NoOp)
226 dyn_cast<MaterializeTemporaryExpr>(Result)) {
241 State = State->bindLoc(Reg, V);
250 State = State->BindExpr(Result, LC, Reg);
261 SVal cond,
bool assumption) {
276 Explicits, Regions, Call);
280 const char *NL,
const char *Sep) {
291 currStmtIdx = StmtIdx;
343 const Stmt *ReferenceStmt,
345 const Stmt *DiagnosticStmt,
348 ReferenceStmt ==
nullptr || isa<ReturnStmt>(ReferenceStmt))
349 &&
"PostStmt is not generally supported by the SymbolReaper yet");
350 assert(LC &&
"Must pass the current (or expiring) LocationContext");
352 if (!DiagnosticStmt) {
353 DiagnosticStmt = ReferenceStmt;
354 assert(DiagnosticStmt &&
"Required for clearing a LocationContext");
357 NumRemoveDeadBindings++;
363 if (!ReferenceStmt) {
365 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
387 Bldr.
generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K);
394 DiagnosticStmt, *
this, K);
409 "Checkers are not allowed to modify the Environment as a part of "
410 "checkDeadSymbols processing.");
412 "Checkers are not allowed to modify the Store as a part of "
413 "checkDeadSymbols processing.");
419 Bldr.
generateNode(DiagnosticStmt, *
I, CleanedCheckerSt, &cleanupTag, K);
431 currStmt->getLocStart(),
432 "Error evaluating statement");
439 CleanedStates.Add(Pred);
444 E = CleanedStates.end();
I !=
E; ++
I) {
447 Visit(currStmt, *
I, DstI);
461 "Error evaluating initializer");
467 cast<CXXConstructorDecl>(stackFrame->getDecl());
470 SVal thisVal = State->getSVal(svalBuilder.
getCXXThis(decl, stackFrame));
479 if (
auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) {
491 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
499 while ((ASE = dyn_cast<ArraySubscriptExpr>(Init)))
502 SVal LValue = State->getSVal(Init, stackFrame);
504 InitVal = State->getSVal(*LValueLoc);
514 InitVal = State->getSVal(BMI->
getInit(), stackFrame);
517 assert(Tmp.
size() == 1 &&
"have not generated any new nodes yet");
518 assert(*Tmp.
begin() == Pred &&
"have not generated any new nodes yet");
522 evalBind(Tmp, Init, Pred, FieldLoc, InitVal,
true, &PP);
563 llvm_unreachable(
"Unexpected dtor kind.");
601 Region = state->getSVal(Region).getAsRegion();
615 SVal ArgVal = State->getSVal(Arg, LCtx);
619 if (State->isNull(ArgVal).isConstrainedTrue()) {
627 Bldr.generateNode(PP, Pred->
getState(), Pred);
653 CurDtor->
getBody(),
true, Pred, Dst);
666 State->getLValue(Member, State->getSVal(ThisVal).castAs<
Loc>());
670 CurDtor->
getBody(),
false, Pred, Dst);
679 if (State->contains<InitializedTemporariesSet>(
683 State = State->remove<InitializedTemporariesSet>(
691 assert(CleanDtorState.
size() <= 1);
693 CleanDtorState.
empty() ? Pred : *CleanDtorState.
begin();
697 false, CleanPred, Dst);
707 if (Pred->
getState()->contains<InitializedTemporariesSet>(
730 if (!State->contains<InitializedTemporariesSet>(
731 std::make_pair(BTE,
Node->getStackFrame()))) {
736 State = State->add<InitializedTemporariesSet>(
737 std::make_pair(BTE,
Node->getStackFrame()));
747 "Error evaluating statement");
751 assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
753 switch (S->getStmtClass()) {
755 case Expr::ObjCIndirectCopyRestoreExprClass:
756 case Stmt::CXXDependentScopeMemberExprClass:
757 case Stmt::CXXTryStmtClass:
758 case Stmt::CXXTypeidExprClass:
759 case Stmt::CXXUuidofExprClass:
760 case Stmt::CXXFoldExprClass:
761 case Stmt::MSPropertyRefExprClass:
762 case Stmt::MSPropertySubscriptExprClass:
763 case Stmt::CXXUnresolvedConstructExprClass:
764 case Stmt::DependentScopeDeclRefExprClass:
765 case Stmt::ArrayTypeTraitExprClass:
766 case Stmt::ExpressionTraitExprClass:
767 case Stmt::UnresolvedLookupExprClass:
768 case Stmt::UnresolvedMemberExprClass:
769 case Stmt::TypoExprClass:
770 case Stmt::CXXNoexceptExprClass:
771 case Stmt::PackExpansionExprClass:
772 case Stmt::SubstNonTypeTemplateParmPackExprClass:
773 case Stmt::FunctionParmPackExprClass:
774 case Stmt::CoroutineBodyStmtClass:
775 case Stmt::CoawaitExprClass:
776 case Stmt::CoreturnStmtClass:
777 case Stmt::CoyieldExprClass:
778 case Stmt::SEHTryStmtClass:
779 case Stmt::SEHExceptStmtClass:
780 case Stmt::SEHLeaveStmtClass:
781 case Stmt::SEHFinallyStmtClass: {
787 case Stmt::ParenExprClass:
788 llvm_unreachable(
"ParenExprs already handled.");
789 case Stmt::GenericSelectionExprClass:
790 llvm_unreachable(
"GenericSelectionExprs already handled.");
793 case Stmt::BreakStmtClass:
794 case Stmt::CaseStmtClass:
795 case Stmt::CompoundStmtClass:
796 case Stmt::ContinueStmtClass:
797 case Stmt::CXXForRangeStmtClass:
798 case Stmt::DefaultStmtClass:
799 case Stmt::DoStmtClass:
800 case Stmt::ForStmtClass:
801 case Stmt::GotoStmtClass:
802 case Stmt::IfStmtClass:
803 case Stmt::IndirectGotoStmtClass:
804 case Stmt::LabelStmtClass:
805 case Stmt::NoStmtClass:
806 case Stmt::NullStmtClass:
807 case Stmt::SwitchStmtClass:
808 case Stmt::WhileStmtClass:
809 case Expr::MSDependentExistsStmtClass:
810 case Stmt::CapturedStmtClass:
811 case Stmt::OMPParallelDirectiveClass:
812 case Stmt::OMPSimdDirectiveClass:
813 case Stmt::OMPForDirectiveClass:
814 case Stmt::OMPForSimdDirectiveClass:
815 case Stmt::OMPSectionsDirectiveClass:
816 case Stmt::OMPSectionDirectiveClass:
817 case Stmt::OMPSingleDirectiveClass:
818 case Stmt::OMPMasterDirectiveClass:
819 case Stmt::OMPCriticalDirectiveClass:
820 case Stmt::OMPParallelForDirectiveClass:
821 case Stmt::OMPParallelForSimdDirectiveClass:
822 case Stmt::OMPParallelSectionsDirectiveClass:
823 case Stmt::OMPTaskDirectiveClass:
824 case Stmt::OMPTaskyieldDirectiveClass:
825 case Stmt::OMPBarrierDirectiveClass:
826 case Stmt::OMPTaskwaitDirectiveClass:
827 case Stmt::OMPTaskgroupDirectiveClass:
828 case Stmt::OMPFlushDirectiveClass:
829 case Stmt::OMPOrderedDirectiveClass:
830 case Stmt::OMPAtomicDirectiveClass:
831 case Stmt::OMPTargetDirectiveClass:
832 case Stmt::OMPTargetDataDirectiveClass:
833 case Stmt::OMPTeamsDirectiveClass:
834 case Stmt::OMPCancellationPointDirectiveClass:
835 case Stmt::OMPCancelDirectiveClass:
836 case Stmt::OMPTaskLoopDirectiveClass:
837 case Stmt::OMPTaskLoopSimdDirectiveClass:
838 case Stmt::OMPDistributeDirectiveClass:
839 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
841 case Stmt::ObjCSubscriptRefExprClass:
842 case Stmt::ObjCPropertyRefExprClass:
843 llvm_unreachable(
"These are handled by PseudoObjectExpr");
845 case Stmt::GNUNullExprClass: {
854 case Stmt::ObjCAtSynchronizedStmtClass:
860 case Stmt::ExprWithCleanupsClass:
864 case Stmt::CXXBindTemporaryExprClass: {
876 case Stmt::DesignatedInitExprClass:
877 case Stmt::DesignatedInitUpdateExprClass:
878 case Stmt::ExtVectorElementExprClass:
879 case Stmt::ImaginaryLiteralClass:
880 case Stmt::ObjCAtCatchStmtClass:
881 case Stmt::ObjCAtFinallyStmtClass:
882 case Stmt::ObjCAtTryStmtClass:
883 case Stmt::ObjCAutoreleasePoolStmtClass:
884 case Stmt::ObjCEncodeExprClass:
885 case Stmt::ObjCIsaExprClass:
886 case Stmt::ObjCProtocolExprClass:
887 case Stmt::ObjCSelectorExprClass:
888 case Stmt::ParenListExprClass:
889 case Stmt::ShuffleVectorExprClass:
890 case Stmt::ConvertVectorExprClass:
891 case Stmt::VAArgExprClass:
892 case Stmt::CUDAKernelCallExprClass:
893 case Stmt::OpaqueValueExprClass:
894 case Stmt::AsTypeExprClass:
895 case Stmt::AtomicExprClass:
900 case Stmt::PredefinedExprClass:
901 case Stmt::AddrLabelExprClass:
902 case Stmt::AttributedStmtClass:
903 case Stmt::IntegerLiteralClass:
904 case Stmt::CharacterLiteralClass:
905 case Stmt::ImplicitValueInitExprClass:
906 case Stmt::CXXScalarValueInitExprClass:
907 case Stmt::CXXBoolLiteralExprClass:
908 case Stmt::ObjCBoolLiteralExprClass:
909 case Stmt::FloatingLiteralClass:
910 case Stmt::NoInitExprClass:
911 case Stmt::SizeOfPackExprClass:
912 case Stmt::StringLiteralClass:
913 case Stmt::ObjCStringLiteralClass:
914 case Stmt::CXXPseudoDestructorExprClass:
915 case Stmt::SubstNonTypeTemplateParmExprClass:
916 case Stmt::CXXNullPtrLiteralExprClass:
917 case Stmt::OMPArraySectionExprClass:
918 case Stmt::TypeTraitExprClass: {
927 case Stmt::CXXDefaultArgExprClass:
928 case Stmt::CXXDefaultInitExprClass: {
938 ArgE = DefE->getExpr();
940 ArgE = DefE->getExpr();
942 llvm_unreachable(
"unknown constant wrapper kind");
944 bool IsTemporary =
false;
946 dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
947 ArgE = MTE->GetTemporaryExpr();
959 State = State->BindExpr(S, LCtx, *ConstantVal);
961 State = createTemporaryRegionIfNeeded(State, LCtx,
973 case Stmt::CXXStdInitializerListExprClass:
974 case Expr::ObjCArrayLiteralClass:
975 case Expr::ObjCDictionaryLiteralClass:
976 case Expr::ObjCBoxedExprClass: {
985 const Expr *Ex = cast<Expr>(
S);
1004 case Stmt::ArraySubscriptExprClass:
1010 case Stmt::GCCAsmStmtClass:
1016 case Stmt::MSAsmStmtClass:
1022 case Stmt::BlockExprClass:
1028 case Stmt::LambdaExprClass:
1039 case Stmt::BinaryOperatorClass: {
1051 state->getSVal(B->
getRHS(),
1071 case Stmt::CXXOperatorCallExprClass: {
1077 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
1078 if (MD->isInstance()) {
1082 createTemporaryRegionIfNeeded(State, LCtx, OCE->
getArg(0));
1083 if (NewState != State) {
1094 case Stmt::CallExprClass:
1095 case Stmt::CXXMemberCallExprClass:
1096 case Stmt::UserDefinedLiteralClass: {
1103 case Stmt::CXXCatchStmtClass: {
1110 case Stmt::CXXTemporaryObjectExprClass:
1111 case Stmt::CXXConstructExprClass: {
1118 case Stmt::CXXNewExprClass: {
1127 case Stmt::CXXDeleteExprClass: {
1134 e = PreVisit.
end(); i != e ; ++i)
1143 case Stmt::ChooseExprClass: {
1151 case Stmt::CompoundAssignOperatorClass:
1157 case Stmt::CompoundLiteralExprClass:
1163 case Stmt::BinaryConditionalOperatorClass:
1164 case Stmt::ConditionalOperatorClass: {
1167 = cast<AbstractConditionalOperator>(
S);
1173 case Stmt::CXXThisExprClass:
1179 case Stmt::DeclRefExprClass: {
1187 case Stmt::DeclStmtClass:
1193 case Stmt::ImplicitCastExprClass:
1194 case Stmt::CStyleCastExprClass:
1195 case Stmt::CXXStaticCastExprClass:
1196 case Stmt::CXXDynamicCastExprClass:
1197 case Stmt::CXXReinterpretCastExprClass:
1198 case Stmt::CXXConstCastExprClass:
1199 case Stmt::CXXFunctionalCastExprClass:
1200 case Stmt::ObjCBridgedCastExprClass: {
1210 e = dstPrevisit.end(); i != e ; ++i) {
1220 case Expr::MaterializeTemporaryExprClass: {
1228 case Stmt::InitListExprClass:
1234 case Stmt::MemberExprClass:
1240 case Stmt::ObjCIvarRefExprClass:
1246 case Stmt::ObjCForCollectionStmtClass:
1252 case Stmt::ObjCMessageExprClass:
1258 case Stmt::ObjCAtThrowStmtClass:
1259 case Stmt::CXXThrowExprClass:
1265 case Stmt::ReturnStmtClass:
1271 case Stmt::OffsetOfExprClass:
1277 case Stmt::UnaryExprOrTypeTraitExprClass:
1284 case Stmt::StmtExprClass: {
1290 &&
"Empty statement expression must have void type.");
1298 state->getSVal(LastExpr,
1304 case Stmt::UnaryOperatorClass: {
1318 case Stmt::PseudoObjectExprClass: {
1338 bool ExprEngine::replayWithoutInlining(
ExplodedNode *N,
1342 assert(CalleeSF && CallerSF);
1349 BeforeProcessingCall = N;
1364 if (SP->getStmt() == CE)
1369 if (!BeforeProcessingCall)
1397 NumTimesRetriedWithoutInlining++;
1414 (isa<ForStmt>(Term) || isa<WhileStmt>(Term) || isa<DoStmt>(Term))))
1435 (*G.
roots_begin())->getLocation().getLocationContext();
1444 replayWithoutInlining(Pred, CalleeLC)))
1446 NumMaxBlockCountReachedInInlined++;
1448 NumMaxBlockCountReached++;
1451 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
1466 const Stmt *Condition,
1470 const Expr *Ex = dyn_cast<
Expr>(Condition);
1475 bool bitsInit =
false;
1477 while (
const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
1484 if (!bitsInit || newBits < bits) {
1489 Ex = CE->getSubExpr();
1499 return state->getSVal(Ex, LCtx);
1531 if (
const Expr *Ex = dyn_cast<Expr>(Condition))
1539 "Temporary destructor branches handled by processBindTemporary.");
1550 for (; I !=
E; ++
I) {
1555 const Stmt *LastStmt = CS->getStmt();
1559 llvm_unreachable(
"could not resolve condition");
1568 assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) &&
1569 "CXXBindTemporaryExprs are handled by processBindTemporary.");
1572 currBldrCtx = &BldCtx;
1582 if (
const Expr *Ex = dyn_cast<Expr>(Condition))
1587 Condition->getLocStart(),
1588 "Error evaluating branch");
1594 if (CheckersOutSet.empty())
1599 E = CheckersOutSet.end();
E !=
I; ++
I) {
1610 if (
const Expr *Ex = dyn_cast<Expr>(Condition)) {
1617 PrevState, Condition,
1638 std::tie(StTrue, StFalse) = PrevState->assume(V);
1656 currBldrCtx =
nullptr;
1671 currBldrCtx = &BuilderCtx;
1673 const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
1675 bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
1679 state = state->add<InitializedGlobalsSet>(VD);
1682 builder.generateNode(state, initHasRun, Pred);
1683 builder.markInfeasible(!initHasRun);
1685 currBldrCtx =
nullptr;
1707 for (iterator
I = builder.
begin(),
E = builder.
end();
I !=
E; ++
I) {
1708 if (
I.getLabel() == L) {
1714 llvm_unreachable(
"No block with label.");
1728 for (iterator
I=builder.
begin(),
E=builder.
end();
I !=
E; ++
I)
1733 static bool stackFrameDoesNotContainInitializedTemporaries(
ExplodedNode &Pred) {
1736 Pred.
getState()->get<InitializedTemporariesSet>();
1737 return std::find_if(Set.begin(), Set.end(),
1739 if (Ctx.second == Frame) {
1741 llvm::errs() <<
"\n";
1743 return Ctx.second == Frame;
1766 E = AfterRemovedDead.
end();
I !=
E; ++
I) {
1784 if (CondV_untested.
isUndef()) {
1795 iterator
I = builder.
begin(), EI = builder.
end();
1796 bool defaultIsFeasible = I == EI;
1798 for ( ; I != EI; ++
I) {
1803 const CaseStmt *Case = I.getCase();
1818 std::tie(StateCase, DefaultSt) =
1819 DefaultSt->assumeWithinInclusiveRange(*NL, V1, V2);
1821 StateCase = DefaultSt;
1829 defaultIsFeasible =
true;
1831 defaultIsFeasible =
false;
1836 if (!defaultIsFeasible)
1868 if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1871 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
1873 const Decl *D = LocCtxt->getDecl();
1875 const auto *DeclRefEx = dyn_cast<
DeclRefExpr>(Ex);
1879 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
1880 MD->getParent()->isLambda()) {
1883 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
1886 const FieldDecl *FD = LambdaCaptureFields[VD];
1890 assert(VD->getType().isConstQualified());
1891 V = state->getLValue(VD, LocCtxt);
1892 IsReference =
false;
1895 svalBuilder.
getCXXThis(MD, LocCtxt->getCurrentStackFrame());
1896 SVal CXXThisVal = state->getSVal(CXXThis);
1897 V = state->getLValue(FD, CXXThisVal);
1901 V = state->getLValue(VD, LocCtxt);
1902 IsReference = VD->getType()->isReferenceType();
1908 if (
const MemRegion *R = V.getAsRegion())
1909 V = state->getSVal(R);
1914 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
1921 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
1924 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
1926 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
1930 if (isa<FieldDecl>(D)) {
1937 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
1942 llvm_unreachable(
"Support for this Decl not implemented.");
1962 ei = checkerPreStmt.
end(); it != ei; ++it) {
1966 state->getSVal(Idx, LCtx),
1967 state->getSVal(Base, LCtx));
1968 Bldr.
generateNode(A, *it, state->BindExpr(A, LCtx, V),
nullptr,
1986 if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
2003 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
2004 if (MD->isInstance())
2005 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2008 state = state->BindExpr(M, LCtx, MDVal);
2015 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2016 SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
2018 FieldDecl *field = cast<FieldDecl>(Member);
2019 SVal L = state->getLValue(field, baseExprVal);
2031 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
2036 if (
const MemRegion *R = L.getAsRegion())
2037 L = state->getSVal(R);
2042 Bldr.
generateNode(M, *
I, state->BindExpr(M, LCtx, L),
nullptr,
2056 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
2063 bool VisitSymbol(
SymbolRef Sym)
override {
2064 Symbols.insert(Sym);
2078 bool escapes =
true;
2082 escapes = !regionLoc->getRegion()->hasStackStorage();
2090 SVal StoredVal = State->getSVal(regionLoc->getRegion());
2091 if (StoredVal != Val)
2092 escapes = (State == (State->bindLoc(*regionLoc, Val)));
2104 CollectReachableSymbolsCallback Scanner =
2105 State->scanReachableSymbols<CollectReachableSymbolsCallback>(Val);
2124 if (!Invalidated || Invalidated->empty())
2138 E = ExplicitRegions.end();
I !=
E; ++
I) {
2140 SymbolsDirectlyInvalidated.insert(R->getSymbol());
2144 for (InvalidatedSymbols::const_iterator
I=Invalidated->begin(),
2145 E = Invalidated->end();
I!=
E; ++
I) {
2147 if (SymbolsDirectlyInvalidated.count(sym))
2149 SymbolsIndirectlyInvalidated.insert(sym);
2152 if (!SymbolsDirectlyInvalidated.empty())
2157 if (!SymbolsIndirectlyInvalidated.empty())
2179 StoreE, *
this, *PP);
2204 state = state->bindLoc(location.
castAs<
Loc>(),
2210 LocReg = LocRegVal->getRegion();
2227 const Expr *LocationE,
2233 const Expr *StoreE = AssignE ? AssignE : LocationE;
2237 evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag,
false);
2246 evalBind(Dst, StoreE, *NI, location, Val,
false);
2251 const Expr *BoundEx,
2258 assert(!location.
getAs<
NonLoc>() &&
"location cannot be a NonLoc.");
2264 dyn_cast_or_null<TypedValueRegion>(location.
getAsRegion())) {
2269 loadReferenceTag(TagProviderName,
"Load Reference");
2271 evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state,
2272 location, &loadReferenceTag,
2273 getContext().getPointerType(RT->getPointeeType()));
2277 state = (*I)->getState();
2278 location = state->getSVal(BoundEx, (*I)->getLocationContext());
2279 evalLoadCommon(Dst, NodeEx, BoundEx, *
I, state, location, tag, LoadTy);
2285 evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy);
2290 const Expr *BoundEx,
2300 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag,
true);
2310 state = (*NI)->getState();
2317 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
2320 Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag,
2327 const Stmt *BoundEx,
2340 BldrTop.takeNodes(Pred);
2353 Bldr.generateNode(NodeEx, Pred, state, &tag);
2357 NodeEx, BoundEx, *
this);
2358 BldrTop.addNodes(Tmp);
2361 std::pair<const ProgramPointTag *, const ProgramPointTag*>
2364 eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
2365 "Eagerly Assume True"),
2366 eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
2367 "Eagerly Assume False");
2368 return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
2369 &eagerlyAssumeBinOpBifurcationFalse);
2390 if (SEV && SEV->isExpression()) {
2391 const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
2395 std::tie(StateTrue, StateFalse) = state->assume(*SEV);
2473 return "color=\"red\",style=\"filled\"";
2476 return "color=\"blue\",style=\"filled\"";
2494 llvm::raw_string_ostream Out(sbuf);
2501 Out <<
"Block Entrance: B"
2521 Out <<
"CallExitBegin";
2525 Out <<
"CallExitEnd";
2529 Out <<
"PostStmtPurgeDeadSymbols";
2533 Out <<
"PreStmtPurgeDeadSymbols";
2537 Out <<
"Epsilon Point";
2552 Out <<
"PostCall: ";
2561 Out <<
"PostInitializer: ";
2583 Out <<
"\\|Terminator: ";
2594 if (isa<SwitchStmt>(T)) {
2598 if (
const CaseStmt *
C = dyn_cast<CaseStmt>(Label)) {
2604 if (
const Stmt *RHS =
C->getRHS()) {
2612 assert (isa<DefaultStmt>(Label));
2613 Out <<
"\\ldefault:";
2617 Out <<
"\\l(implicit) default:";
2619 else if (isa<IndirectGotoStmt>(T)) {
2623 Out <<
"\\lCondition: ";
2637 Out <<
"\\|Control-flow based on\\lUndefined value.\\l";
2645 assert(S !=
nullptr &&
"Expecting non-null Stmt");
2647 Out << S->getStmtClassName() <<
' ' << (
const void*) S <<
' ';
2650 printLocation(Out, S->getLocStart());
2653 Out <<
"\\lPreStmt\\l;";
2655 Out <<
"\\lPostLoad\\l;";
2657 Out <<
"\\lPostStore\\l";
2659 Out <<
"\\lPostLValue\\l";
2665 Out <<
"\\|Implicit-Null Dereference.\\l";
2667 Out <<
"\\|Explicit-Null Dereference.\\l";
2669 Out <<
"\\|Dereference of undefialied value.\\l";
2671 Out <<
"\\|Store to Undefined Loc.";
2673 Out <<
"\\|Result of operation is undefined.";
2675 Out <<
"\\|Call to function marked \"noreturn\".";
2677 Out <<
"\\|Call to NULL/Undefined.";
2679 Out <<
"\\|Argument in call is undefined";
2687 Out <<
"\\|StateID: " << (
const void*) state.get()
2688 <<
" NodeID: " << (
const void*) N <<
"\\|";
2689 state->printDOT(Out);
2706 std::vector<const ExplodedNode*> Src;
2711 const_cast<BugType*>(*I)->FlushReports(BR);
2717 if (N) Src.push_back(N);
2739 std::unique_ptr<ExplodedGraph> TrimmedG(G.
trim(Nodes));
2741 if (!TrimmedG.get())
2742 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
2744 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
Decl - This represents one declaration (or definition), e.g.
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)
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)
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.
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.
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 print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine()) const
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
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
CK_ArrayToPointerDecay - Array to pointer decay.
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.
CK_DerivedToBase - A conversion from a C++ class pointer to a base class pointer. ...
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
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 print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) 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
CK_UncheckedDerivedToBase - A conversion from a C++ class pointer/reference to a base class that can ...
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 VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
const LangOptions & getLangOpts() const
CK_NoOp - A conversion which does not affect the type other than (possibly) adding qualifiers...
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...