32 #include "llvm/ADT/Statistic.h" 33 #include "llvm/Support/SaveAndRestore.h" 34 #include "llvm/Support/raw_ostream.h" 37 #include "llvm/Support/GraphWriter.h" 40 using namespace clang;
44 #define DEBUG_TYPE "ExprEngine" 47 "The # of times RemoveDeadBindings is called");
49 "The # of aborted paths due to reaching the maximum block count in " 50 "a top level function");
51 STATISTIC(NumMaxBlockCountReachedInInlined,
52 "The # of aborted paths due to reaching the maximum block count in " 53 "an inlined function");
55 "The # of times we re-evaluated a call without inlining");
57 typedef std::pair<const CXXBindTemporaryExpr *, const StackFrameContext *>
70 static const char* TagProviderName =
"ExprEngine";
77 AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
80 StateMgr(getContext(), mgr.getStoreManagerCreator(),
81 mgr.getConstraintManagerCreator(), G.getAllocator(),
83 SymMgr(StateMgr.getSymbolManager()),
84 svalBuilder(StateMgr.getSValBuilder()),
85 currStmtIdx(0), currBldrCtx(nullptr),
86 ObjCNoRet(mgr.getASTContext()),
87 ObjCGCEnabled(gcEnabled), BR(mgr, *this),
88 VisitedCallees(VisitedCalleesIn),
89 HowToInline(HowToInlineIn)
92 if (TrimInterval != 0) {
115 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
119 if (!II || !(II->
getName() ==
"main" && FD->getNumParams() > 0))
128 const MemRegion *R = state->getRegion(PD, InitLoc);
154 const MemRegion *R = state->getRegion(SelfD, InitLoc);
159 state = state->assume(*LV,
true);
160 assert(state &&
"'self' cannot be null");
165 if (!MD->isStatic()) {
172 SVal V = state->getSVal(L);
174 state = state->assume(*LV,
true);
175 assert(state &&
"'this' cannot be null");
187 const Expr *InitWithAdjustments,
188 const Expr *Result) {
194 SVal InitValWithAdjustments = State->getSVal(InitWithAdjustments, LC);
200 Result = InitWithAdjustments;
204 assert(!InitValWithAdjustments.
getAs<
Loc>() ||
238 CommaLHSs, Adjustments);
242 dyn_cast<MaterializeTemporaryExpr>(Result)) {
256 for (
auto I = Adjustments.rbegin(), E = Adjustments.rend(); I != E; ++I) {
267 State = State->bindDefault(Reg,
UnknownVal(), LC);
280 SVal InitVal = State->getSVal(Init, LC);
284 State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
287 if (InitValWithAdjustments.
isUnknown()) {
291 Result, LC, InitWithAdjustments->
getType(),
295 State->bindLoc(Reg.
castAs<
Loc>(), InitValWithAdjustments, LC,
false);
297 State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
303 State = State->BindExpr(Result, LC, Reg);
318 SVal cond,
bool assumption) {
335 const char *NL,
const char *Sep) {
346 currStmtIdx = StmtIdx;
403 const Stmt *ReferenceStmt,
405 const Stmt *DiagnosticStmt,
408 ReferenceStmt ==
nullptr || isa<ReturnStmt>(ReferenceStmt))
409 &&
"PostStmt is not generally supported by the SymbolReaper yet");
410 assert(LC &&
"Must pass the current (or expiring) LocationContext");
412 if (!DiagnosticStmt) {
413 DiagnosticStmt = ReferenceStmt;
414 assert(DiagnosticStmt &&
"Required for clearing a LocationContext");
417 NumRemoveDeadBindings++;
423 if (!ReferenceStmt) {
425 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
447 Bldr.
generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K);
454 DiagnosticStmt, *
this, K);
461 I = CheckedSet.
begin(), E = CheckedSet.
end(); I != E; ++I) {
469 "Checkers are not allowed to modify the Environment as a part of " 470 "checkDeadSymbols processing.");
472 "Checkers are not allowed to modify the Store as a part of " 473 "checkDeadSymbols processing.");
479 Bldr.
generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K);
492 "Error evaluating statement");
499 CleanedStates.Add(Pred);
504 E = CleanedStates.end(); I != E; ++I) {
507 Visit(currStmt, *I, DstI);
518 "Error evaluating end of the loop");
539 "Error evaluating initializer");
545 cast<CXXConstructorDecl>(stackFrame->getDecl());
548 SVal thisVal = State->getSVal(svalBuilder.
getCXXThis(decl, stackFrame));
557 if (
auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) {
569 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
577 while ((ASE = dyn_cast<ArraySubscriptExpr>(Init)))
580 SVal LValue = State->getSVal(Init, stackFrame);
583 InitVal = State->getSVal(*LValueLoc);
593 InitVal = State->getSVal(BMI->
getInit(), stackFrame);
596 assert(Tmp.
size() == 1 &&
"have not generated any new nodes yet");
597 assert(*Tmp.
begin() == Pred &&
"have not generated any new nodes yet");
601 evalBind(Tmp, Init, Pred, FieldLoc, InitVal,
true, &PP);
642 llvm_unreachable(
"Unexpected dtor kind.");
679 const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
688 varType = cast<TypedValueRegion>(Region)->getValueType();
702 SVal ArgVal = State->getSVal(Arg, LCtx);
706 if (State->isNull(ArgVal).isConstrainedTrue()) {
714 Bldr.generateNode(PP, Pred->
getState(), Pred);
740 CurDtor->
getBody(),
true, Pred, Dst);
753 State->getLValue(Member, State->getSVal(ThisVal).castAs<
Loc>());
757 CurDtor->
getBody(),
false, Pred, Dst);
766 if (State->contains<InitializedTemporariesSet>(
770 State = State->remove<InitializedTemporariesSet>(
778 assert(CleanDtorState.
size() <= 1);
780 CleanDtorState.
empty() ? Pred : *CleanDtorState.
begin();
784 false, CleanPred, Dst);
794 if (Pred->
getState()->contains<InitializedTemporariesSet>(
817 if (!State->contains<InitializedTemporariesSet>(
818 std::make_pair(BTE,
Node->getStackFrame()))) {
823 State = State->add<InitializedTemporariesSet>(
824 std::make_pair(BTE,
Node->getStackFrame()));
831 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
838 bool VisitSymbol(
SymbolRef Sym)
override {
849 "Error evaluating statement");
853 assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
857 case Expr::ObjCIndirectCopyRestoreExprClass:
858 case Stmt::CXXDependentScopeMemberExprClass:
859 case Stmt::CXXInheritedCtorInitExprClass:
860 case Stmt::CXXTryStmtClass:
861 case Stmt::CXXTypeidExprClass:
862 case Stmt::CXXUuidofExprClass:
863 case Stmt::CXXFoldExprClass:
864 case Stmt::MSPropertyRefExprClass:
865 case Stmt::MSPropertySubscriptExprClass:
866 case Stmt::CXXUnresolvedConstructExprClass:
867 case Stmt::DependentScopeDeclRefExprClass:
868 case Stmt::ArrayTypeTraitExprClass:
869 case Stmt::ExpressionTraitExprClass:
870 case Stmt::UnresolvedLookupExprClass:
871 case Stmt::UnresolvedMemberExprClass:
872 case Stmt::TypoExprClass:
873 case Stmt::CXXNoexceptExprClass:
874 case Stmt::PackExpansionExprClass:
875 case Stmt::SubstNonTypeTemplateParmPackExprClass:
876 case Stmt::FunctionParmPackExprClass:
877 case Stmt::CoroutineBodyStmtClass:
878 case Stmt::CoawaitExprClass:
879 case Stmt::DependentCoawaitExprClass:
880 case Stmt::CoreturnStmtClass:
881 case Stmt::CoyieldExprClass:
882 case Stmt::SEHTryStmtClass:
883 case Stmt::SEHExceptStmtClass:
884 case Stmt::SEHLeaveStmtClass:
885 case Stmt::SEHFinallyStmtClass:
886 case Stmt::OMPParallelDirectiveClass:
887 case Stmt::OMPSimdDirectiveClass:
888 case Stmt::OMPForDirectiveClass:
889 case Stmt::OMPForSimdDirectiveClass:
890 case Stmt::OMPSectionsDirectiveClass:
891 case Stmt::OMPSectionDirectiveClass:
892 case Stmt::OMPSingleDirectiveClass:
893 case Stmt::OMPMasterDirectiveClass:
894 case Stmt::OMPCriticalDirectiveClass:
895 case Stmt::OMPParallelForDirectiveClass:
896 case Stmt::OMPParallelForSimdDirectiveClass:
897 case Stmt::OMPParallelSectionsDirectiveClass:
898 case Stmt::OMPTaskDirectiveClass:
899 case Stmt::OMPTaskyieldDirectiveClass:
900 case Stmt::OMPBarrierDirectiveClass:
901 case Stmt::OMPTaskwaitDirectiveClass:
902 case Stmt::OMPTaskgroupDirectiveClass:
903 case Stmt::OMPFlushDirectiveClass:
904 case Stmt::OMPOrderedDirectiveClass:
905 case Stmt::OMPAtomicDirectiveClass:
906 case Stmt::OMPTargetDirectiveClass:
907 case Stmt::OMPTargetDataDirectiveClass:
908 case Stmt::OMPTargetEnterDataDirectiveClass:
909 case Stmt::OMPTargetExitDataDirectiveClass:
910 case Stmt::OMPTargetParallelDirectiveClass:
911 case Stmt::OMPTargetParallelForDirectiveClass:
912 case Stmt::OMPTargetUpdateDirectiveClass:
913 case Stmt::OMPTeamsDirectiveClass:
914 case Stmt::OMPCancellationPointDirectiveClass:
915 case Stmt::OMPCancelDirectiveClass:
916 case Stmt::OMPTaskLoopDirectiveClass:
917 case Stmt::OMPTaskLoopSimdDirectiveClass:
918 case Stmt::OMPDistributeDirectiveClass:
919 case Stmt::OMPDistributeParallelForDirectiveClass:
920 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
921 case Stmt::OMPDistributeSimdDirectiveClass:
922 case Stmt::OMPTargetParallelForSimdDirectiveClass:
923 case Stmt::OMPTargetSimdDirectiveClass:
924 case Stmt::OMPTeamsDistributeDirectiveClass:
925 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
926 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
927 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
928 case Stmt::OMPTargetTeamsDirectiveClass:
929 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
930 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
931 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
932 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
933 case Stmt::CapturedStmtClass:
936 Engine.addAbortedBlock(node, currBldrCtx->getBlock());
940 case Stmt::ParenExprClass:
941 llvm_unreachable(
"ParenExprs already handled.");
942 case Stmt::GenericSelectionExprClass:
943 llvm_unreachable(
"GenericSelectionExprs already handled.");
946 case Stmt::BreakStmtClass:
947 case Stmt::CaseStmtClass:
948 case Stmt::CompoundStmtClass:
949 case Stmt::ContinueStmtClass:
950 case Stmt::CXXForRangeStmtClass:
951 case Stmt::DefaultStmtClass:
952 case Stmt::DoStmtClass:
953 case Stmt::ForStmtClass:
954 case Stmt::GotoStmtClass:
955 case Stmt::IfStmtClass:
956 case Stmt::IndirectGotoStmtClass:
957 case Stmt::LabelStmtClass:
959 case Stmt::NullStmtClass:
960 case Stmt::SwitchStmtClass:
961 case Stmt::WhileStmtClass:
962 case Expr::MSDependentExistsStmtClass:
963 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
965 case Stmt::ObjCSubscriptRefExprClass:
966 case Stmt::ObjCPropertyRefExprClass:
967 llvm_unreachable(
"These are handled by PseudoObjectExpr");
969 case Stmt::GNUNullExprClass: {
973 svalBuilder.makeIntValWithPtrWidth(0,
false));
978 case Stmt::ObjCAtSynchronizedStmtClass:
984 case Stmt::ExprWithCleanupsClass:
988 case Stmt::CXXBindTemporaryExprClass: {
1000 case Stmt::DesignatedInitExprClass:
1001 case Stmt::DesignatedInitUpdateExprClass:
1002 case Stmt::ArrayInitLoopExprClass:
1003 case Stmt::ArrayInitIndexExprClass:
1004 case Stmt::ExtVectorElementExprClass:
1005 case Stmt::ImaginaryLiteralClass:
1006 case Stmt::ObjCAtCatchStmtClass:
1007 case Stmt::ObjCAtFinallyStmtClass:
1008 case Stmt::ObjCAtTryStmtClass:
1009 case Stmt::ObjCAutoreleasePoolStmtClass:
1010 case Stmt::ObjCEncodeExprClass:
1011 case Stmt::ObjCIsaExprClass:
1012 case Stmt::ObjCProtocolExprClass:
1013 case Stmt::ObjCSelectorExprClass:
1014 case Stmt::ParenListExprClass:
1015 case Stmt::ShuffleVectorExprClass:
1016 case Stmt::ConvertVectorExprClass:
1017 case Stmt::VAArgExprClass:
1018 case Stmt::CUDAKernelCallExprClass:
1019 case Stmt::OpaqueValueExprClass:
1020 case Stmt::AsTypeExprClass:
1025 case Stmt::PredefinedExprClass:
1026 case Stmt::AddrLabelExprClass:
1027 case Stmt::AttributedStmtClass:
1028 case Stmt::IntegerLiteralClass:
1029 case Stmt::CharacterLiteralClass:
1030 case Stmt::ImplicitValueInitExprClass:
1031 case Stmt::CXXScalarValueInitExprClass:
1032 case Stmt::CXXBoolLiteralExprClass:
1033 case Stmt::ObjCBoolLiteralExprClass:
1034 case Stmt::ObjCAvailabilityCheckExprClass:
1035 case Stmt::FloatingLiteralClass:
1036 case Stmt::NoInitExprClass:
1037 case Stmt::SizeOfPackExprClass:
1038 case Stmt::StringLiteralClass:
1039 case Stmt::ObjCStringLiteralClass:
1040 case Stmt::CXXPseudoDestructorExprClass:
1041 case Stmt::SubstNonTypeTemplateParmExprClass:
1042 case Stmt::CXXNullPtrLiteralExprClass:
1043 case Stmt::OMPArraySectionExprClass:
1044 case Stmt::TypeTraitExprClass: {
1053 case Stmt::CXXDefaultArgExprClass:
1054 case Stmt::CXXDefaultInitExprClass: {
1064 ArgE = DefE->getExpr();
1066 ArgE = DefE->getExpr();
1068 llvm_unreachable(
"unknown constant wrapper kind");
1070 bool IsTemporary =
false;
1072 dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
1073 ArgE = MTE->GetTemporaryExpr();
1085 State = State->BindExpr(S, LCtx, *ConstantVal);
1087 State = createTemporaryRegionIfNeeded(State, LCtx,
1099 case Stmt::CXXStdInitializerListExprClass:
1100 case Expr::ObjCArrayLiteralClass:
1101 case Expr::ObjCDictionaryLiteralClass:
1102 case Expr::ObjCBoxedExprClass: {
1111 const Expr *Ex = cast<Expr>(S);
1118 SVal result = svalBuilder.conjureSymbolVal(
nullptr, Ex, LCtx,
1120 currBldrCtx->blockCount());
1125 if (!(isa<ObjCBoxedExpr>(Ex) &&
1126 !cast<ObjCBoxedExpr>(Ex)->getSubExpr()
1128 for (
auto Child : Ex->
children()) {
1131 SVal Val = State->getSVal(Child, LCtx);
1133 CollectReachableSymbolsCallback Scanner =
1134 State->scanReachableSymbols<CollectReachableSymbolsCallback>(
1139 State, EscapedSymbols,
1151 case Stmt::ArraySubscriptExprClass:
1157 case Stmt::GCCAsmStmtClass:
1163 case Stmt::MSAsmStmtClass:
1169 case Stmt::BlockExprClass:
1175 case Stmt::LambdaExprClass:
1176 if (AMgr.options.shouldInlineLambdas()) {
1182 Engine.addAbortedBlock(node, currBldrCtx->getBlock());
1186 case Stmt::BinaryOperatorClass: {
1198 state->getSVal(B->
getRHS(),
1205 if (AMgr.options.eagerlyAssumeBinOpBifurcation &&
1218 case Stmt::CXXOperatorCallExprClass: {
1224 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
1225 if (MD->isInstance()) {
1229 createTemporaryRegionIfNeeded(State, LCtx, OCE->
getArg(0));
1230 if (NewState != State) {
1242 case Stmt::CallExprClass:
1243 case Stmt::CXXMemberCallExprClass:
1244 case Stmt::UserDefinedLiteralClass: {
1251 case Stmt::CXXCatchStmtClass: {
1258 case Stmt::CXXTemporaryObjectExprClass:
1259 case Stmt::CXXConstructExprClass: {
1266 case Stmt::CXXNewExprClass: {
1275 case Stmt::CXXDeleteExprClass: {
1282 e = PreVisit.
end(); i != e ; ++i)
1291 case Stmt::ChooseExprClass: {
1299 case Stmt::CompoundAssignOperatorClass:
1305 case Stmt::CompoundLiteralExprClass:
1311 case Stmt::BinaryConditionalOperatorClass:
1312 case Stmt::ConditionalOperatorClass: {
1315 = cast<AbstractConditionalOperator>(S);
1321 case Stmt::CXXThisExprClass:
1327 case Stmt::DeclRefExprClass: {
1335 case Stmt::DeclStmtClass:
1341 case Stmt::ImplicitCastExprClass:
1342 case Stmt::CStyleCastExprClass:
1343 case Stmt::CXXStaticCastExprClass:
1344 case Stmt::CXXDynamicCastExprClass:
1345 case Stmt::CXXReinterpretCastExprClass:
1346 case Stmt::CXXConstCastExprClass:
1347 case Stmt::CXXFunctionalCastExprClass:
1348 case Stmt::ObjCBridgedCastExprClass: {
1350 const CastExpr *C = cast<CastExpr>(S);
1360 case Expr::MaterializeTemporaryExprClass: {
1367 e = dstPrevisit.end(); i != e ; ++i) {
1375 case Stmt::InitListExprClass:
1381 case Stmt::MemberExprClass:
1387 case Stmt::AtomicExprClass:
1393 case Stmt::ObjCIvarRefExprClass:
1399 case Stmt::ObjCForCollectionStmtClass:
1405 case Stmt::ObjCMessageExprClass:
1411 case Stmt::ObjCAtThrowStmtClass:
1412 case Stmt::CXXThrowExprClass:
1418 case Stmt::ReturnStmtClass:
1424 case Stmt::OffsetOfExprClass:
1430 case Stmt::UnaryExprOrTypeTraitExprClass:
1437 case Stmt::StmtExprClass: {
1438 const StmtExpr *SE = cast<StmtExpr>(S);
1443 &&
"Empty statement expression must have void type.");
1451 state->getSVal(LastExpr,
1457 case Stmt::UnaryOperatorClass: {
1460 if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->
getOpcode() == UO_LNot)) {
1471 case Stmt::PseudoObjectExprClass: {
1491 bool ExprEngine::replayWithoutInlining(
ExplodedNode *N,
1495 assert(CalleeSF && CallerSF);
1502 BeforeProcessingCall = N;
1517 if (SP->getStmt() == CE)
1522 if (!BeforeProcessingCall)
1539 ExplodedNode *NewNode = G.getNode(NewNodeLoc, NewNodeState,
false, &IsNew);
1550 NumTimesRetriedWithoutInlining++;
1561 if(AMgr.options.shouldUnrollLoops()) {
1562 unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
1566 Pred, maxBlockVisitOnPath);
1567 if (NewState != Pred->
getState()) {
1582 if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
1583 AMgr.options.shouldWidenLoops()) {
1586 (isa<ForStmt>(Term) || isa<WhileStmt>(Term) || isa<DoStmt>(Term))))
1597 if (BlockCount >= AMgr.options.maxBlockVisitOnPath) {
1607 (*G.roots_begin())->getLocation().getLocationContext();
1609 Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->
getDecl());
1615 if ((!AMgr.options.NoRetryExhausted &&
1616 replayWithoutInlining(Pred, CalleeLC)))
1618 NumMaxBlockCountReachedInInlined++;
1620 NumMaxBlockCountReached++;
1623 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
1638 const Stmt *Condition,
1642 const Expr *Ex = dyn_cast<
Expr>(Condition);
1647 bool bitsInit =
false;
1649 while (
const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
1656 if (!bitsInit || newBits < bits) {
1661 Ex = CE->getSubExpr();
1671 return state->getSVal(Ex, LCtx);
1703 if (
const Expr *Ex = dyn_cast<Expr>(Condition))
1704 Condition = Ex->IgnoreParens();
1711 "Temporary destructor branches handled by processBindTemporary.");
1722 for (; I != E; ++I) {
1727 const Stmt *LastStmt = CS->getStmt();
1731 llvm_unreachable(
"could not resolve condition");
1740 assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) &&
1741 "CXXBindTemporaryExprs are handled by processBindTemporary.");
1744 currBldrCtx = &BldCtx;
1754 if (
const Expr *Ex = dyn_cast<Expr>(Condition))
1755 Condition = Ex->IgnoreParens();
1760 "Error evaluating branch");
1766 if (CheckersOutSet.empty())
1771 E = CheckersOutSet.end(); E != I; ++I) {
1782 if (
const Expr *Ex = dyn_cast<Expr>(Condition)) {
1783 if (Ex->getType()->isIntegralOrEnumerationType()) {
1789 PrevState, Condition,
1810 std::tie(StTrue, StFalse) = PrevState->assume(V);
1828 currBldrCtx =
nullptr;
1843 currBldrCtx = &BuilderCtx;
1847 bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
1851 state = state->add<InitializedGlobalsSet>(VD);
1854 builder.generateNode(state, initHasRun, Pred);
1855 builder.markInfeasible(!initHasRun);
1857 currBldrCtx =
nullptr;
1879 for (iterator I = builder.
begin(), E = builder.
end(); I != E; ++I) {
1880 if (I.getLabel() == L) {
1886 llvm_unreachable(
"No block with label.");
1900 for (iterator I=builder.
begin(), E=builder.
end(); I != E; ++I)
1905 static bool stackFrameDoesNotContainInitializedTemporaries(
ExplodedNode &Pred) {
1908 Pred.
getState()->get<InitializedTemporariesSet>();
1909 return std::find_if(Set.begin(), Set.end(),
1911 if (Ctx.second == Frame) {
1913 llvm::errs() <<
"\n";
1915 return Ctx.second == Frame;
1937 StateMgr.EndPath(Pred->
getState());
1947 E = AfterRemovedDead.
end(); I != E; ++I) {
1954 Engine.enqueueEndOfFunction(Dst, RS);
1965 if (CondV_untested.
isUndef()) {
1976 iterator I = builder.
begin(), EI = builder.
end();
1977 bool defaultIsFeasible = I == EI;
1979 for ( ; I != EI; ++I) {
1984 const CaseStmt *Case = I.getCase();
1999 std::tie(StateCase, DefaultSt) =
2000 DefaultSt->assumeInclusiveRange(*NL, V1, V2);
2002 StateCase = DefaultSt;
2010 defaultIsFeasible =
true;
2012 defaultIsFeasible =
false;
2017 if (!defaultIsFeasible)
2049 if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
2052 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
2054 const Decl *D = LocCtxt->getDecl();
2056 const auto *DeclRefEx = dyn_cast<
DeclRefExpr>(Ex);
2059 if (AMgr.options.shouldInlineLambdas() && DeclRefEx &&
2060 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
2061 MD->getParent()->isLambda()) {
2064 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
2067 const FieldDecl *FD = LambdaCaptureFields[VD];
2071 assert(VD->getType().isConstQualified());
2072 V = state->getLValue(VD, LocCtxt);
2073 IsReference =
false;
2076 svalBuilder.getCXXThis(MD, LocCtxt->getCurrentStackFrame());
2077 SVal CXXThisVal = state->getSVal(CXXThis);
2078 V = state->getLValue(FD, CXXThisVal);
2082 V = state->getLValue(VD, LocCtxt);
2083 IsReference = VD->getType()->isReferenceType();
2089 if (
const MemRegion *R = V.getAsRegion())
2090 V = state->getSVal(R);
2095 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
2101 SVal V = svalBuilder.makeIntVal(ED->getInitVal());
2102 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
2105 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
2106 SVal V = svalBuilder.getFunctionPointer(FD);
2107 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
2111 if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
2117 SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx,
getContext().VoidPtrTy,
2118 currBldrCtx->blockCount());
2120 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
2125 llvm_unreachable(
"Support for this Decl not implemented.");
2149 for (
auto *
Node : CheckerPreStmt) {
2153 if (IsGLValueLike) {
2155 state->getSVal(Idx, LCtx),
2156 state->getSVal(Base, LCtx));
2159 }
else if (IsVectorType) {
2163 llvm_unreachable(
"Array subscript should be an lValue when not \ 2164 a vector and not a forbidden lvalue type");
2184 if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
2201 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
2202 if (MD->isInstance())
2203 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2205 SVal MDVal = svalBuilder.getFunctionPointer(MD);
2206 state = state->BindExpr(M, LCtx, MDVal);
2213 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2214 SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
2216 FieldDecl *field = cast<FieldDecl>(Member);
2217 SVal L = state->getLValue(field, baseExprVal);
2228 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
2229 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
2234 if (
const MemRegion *R = L.getAsRegion())
2235 L = state->getSVal(R);
2240 Bldr.
generateNode(M, *I, state->BindExpr(M, LCtx, L),
nullptr,
2270 for (
unsigned SI = 0, Count = AE->
getNumSubExprs(); SI != Count; SI++) {
2272 SVal SubExprVal = State->getSVal(SubExpr, LCtx);
2273 ValuesToInvalidate.push_back(SubExprVal);
2276 State = State->invalidateRegions(ValuesToInvalidate, AE,
2277 currBldrCtx->blockCount(),
2283 State = State->BindExpr(AE, LCtx, ResultVal);
2301 bool escapes =
true;
2305 escapes = !regionLoc->getRegion()->hasStackStorage();
2313 SVal StoredVal = State->getSVal(regionLoc->getRegion());
2314 if (StoredVal != Val)
2315 escapes = (State == (State->bindLoc(*regionLoc, Val, LCtx)));
2327 CollectReachableSymbolsCallback Scanner =
2328 State->scanReachableSymbols<CollectReachableSymbolsCallback>(Val);
2347 if (!Invalidated || Invalidated->empty())
2361 E = ExplicitRegions.end(); I != E; ++I) {
2363 SymbolsDirectlyInvalidated.insert(R->getSymbol());
2367 for (InvalidatedSymbols::const_iterator I=Invalidated->begin(),
2368 E = Invalidated->end(); I!=E; ++I) {
2370 if (SymbolsDirectlyInvalidated.count(sym))
2372 SymbolsIndirectlyInvalidated.insert(sym);
2375 if (!SymbolsDirectlyInvalidated.empty())
2380 if (!SymbolsIndirectlyInvalidated.empty())
2402 StoreE, *
this, *PP);
2427 state = state->bindLoc(location.
castAs<
Loc>(),
2428 Val, LC, !atDeclInit);
2433 LocReg = LocRegVal->getRegion();
2450 const Expr *LocationE,
2456 const Expr *StoreE = AssignE ? AssignE : LocationE;
2460 evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag,
false);
2469 evalBind(Dst, StoreE, *NI, location, Val,
false);
2474 const Expr *BoundEx,
2481 assert(!location.
getAs<
NonLoc>() &&
"location cannot be a NonLoc.");
2487 dyn_cast_or_null<TypedValueRegion>(location.
getAsRegion())) {
2489 QualType ValTy = TR->getValueType();
2492 loadReferenceTag(TagProviderName,
"Load Reference");
2494 evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state,
2495 location, &loadReferenceTag,
2496 getContext().getPointerType(RT->getPointeeType()));
2500 state = (*I)->getState();
2501 location = state->getSVal(BoundEx, (*I)->getLocationContext());
2502 evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy);
2508 evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy);
2513 const Expr *BoundEx,
2523 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag,
true);
2533 state = (*NI)->getState();
2540 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
2543 Bldr.
generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag,
2550 const Stmt *BoundEx,
2580 NodeEx, BoundEx, *
this);
2584 std::pair<const ProgramPointTag *, const ProgramPointTag*>
2587 eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
2588 "Eagerly Assume True"),
2589 eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
2590 "Eagerly Assume False");
2591 return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
2592 &eagerlyAssumeBinOpBifurcationFalse);
2613 if (SEV && SEV->isExpression()) {
2614 const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
2618 std::tie(StateTrue, StateFalse) = state->assume(*SEV);
2622 SVal Val = svalBuilder.makeIntVal(1U, Ex->
getType());
2629 SVal Val = svalBuilder.makeIntVal(0U, Ex->
getType());
2701 SLoc.
print(Out, *GraphPrintSourceManager);
2707 llvm::raw_string_ostream Out(sbuf);
2714 Out <<
"Block Entrance: B" 2728 Out <<
"CallExitBegin";
2732 Out <<
"CallExitEnd";
2736 Out <<
"PostStmtPurgeDeadSymbols";
2740 Out <<
"PreStmtPurgeDeadSymbols";
2744 Out <<
"Epsilon Point";
2765 Out <<
"PostCall: ";
2774 Out <<
"PostInitializer: ";
2796 Out <<
"\\|Terminator: ";
2807 if (isa<SwitchStmt>(
T)) {
2811 if (
const CaseStmt *
C = dyn_cast<CaseStmt>(Label)) {
2817 if (
const Stmt *RHS =
C->getRHS()) {
2825 assert (isa<DefaultStmt>(Label));
2826 Out <<
"\\ldefault:";
2830 Out <<
"\\l(implicit) default:";
2832 else if (isa<IndirectGotoStmt>(
T)) {
2836 Out <<
"\\lCondition: ";
2851 assert(S !=
nullptr &&
"Expecting non-null Stmt");
2859 Out <<
"\\lPreStmt\\l;";
2861 Out <<
"\\lPostLoad\\l;";
2863 Out <<
"\\lPostStore\\l";
2865 Out <<
"\\lPostLValue\\l";
2872 Out <<
"\\|StateID: " << (
const void*) state.get()
2873 <<
" NodeID: " << (
const void*) N <<
"\\|";
2876 Out <<
"Location context stack (from current to outer):\\l";
2879 for (; LC; LC = LC->
getParent(), ++Idx) {
2880 Out << Idx <<
". (" << (
const void *)LC <<
") ";
2884 Out <<
"Calling " << D->getQualifiedNameAsString();
2886 Out <<
"Calling anonymous code";
2887 if (
const Stmt *S = cast<StackFrameContext>(LC)->getCallSite()) {
2889 printLocation2(Out, S->getLocStart());
2893 Out <<
"Invoking block";
2894 if (
const Decl *D = cast<BlockInvocationContext>(LC)->getBlockDecl()) {
2895 Out <<
" defined at ";
2896 printLocation2(Out, D->getLocStart());
2900 Out <<
"Entering scope";
2908 state->printDOT(Out);
2925 std::vector<const ExplodedNode*> Src;
2930 const_cast<BugType*>(*I)->FlushReports(BR);
2934 EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) {
2936 if (N) Src.push_back(N);
2942 GraphPrintCheckerState =
this;
2945 llvm::ViewGraph(*G.roots_begin(),
"ExprEngine");
2947 GraphPrintCheckerState =
nullptr;
2948 GraphPrintSourceManager =
nullptr;
2955 GraphPrintCheckerState =
this;
2958 std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
2960 if (!TrimmedG.get())
2961 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
2963 llvm::ViewGraph(*TrimmedG->roots_begin(),
"TrimmedExprEngine");
2965 GraphPrintCheckerState =
nullptr;
2966 GraphPrintSourceManager =
nullptr;
A call to an overloaded operator written using operator syntax.
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
CFGNewAllocator - Represents C++ allocator call.
This represents a GCC inline-assembly statement extension.
An instance of this class is created to represent a function declaration or definition.
TypedValueRegion - An abstract class representing regions having a typed value.
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const LocationContext *LCtx)
Expr * getInit() const
Get the initializer.
void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArraySubscriptExpr - Transfer function for array accesses.
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred)
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
bool isMemberPointerType() const
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
void markInfeasible(bool branch)
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr *> &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
const Stmt * getStmt() const
succ_iterator succ_begin()
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.
bool isCForbiddenLValueType() const
Determine whether expressions of the given type are forbidden from being lvalues in C...
CompoundStmt * getSubStmt()
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path...
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
Stmt - This represents one statement.
Information about invalidation for a particular region/symbol.
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.
static const Stmt * getRightmostLeaf(const Stmt *Condition)
unsigned getBlockID() const
const CFGBlock * getSrc() const
void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMSAsmStmt - Transfer function logic for MS inline asm.
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...
FunctionDecl * getOperatorNew() const
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
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 CastExpr * BasePath
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T)
static ExprEngine * GraphPrintCheckerState
Expr * getFalseExpr() const
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.
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 *)
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
const ProgramStateRef & getState() const
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)
Represents a point when we exit a loop.
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
bool isIndirectMemberInitializer() const
bool isConsumedExpr(Expr *E) const
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...
const T * getAs() const
Member-template getAs<specific type>'.
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.
ObjCMethodDecl - Represents an instance or class method declaration.
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
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.
bool isUnrolledState(ProgramStateRef State)
Returns if the given State indicates that is inside a completely unrolled loop.
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const Stmt * getTriggerStmt() const
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.
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
BoundNodesTreeBuilder Nodes
void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void ProcessLoopExit(const Stmt *S, ExplodedNode *Pred)
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 char * getStmtClassName() 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
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
A pointer escapes due to binding its value to a location that the analyzer cannot track...
void print(raw_ostream &OS, const SourceManager &SM) const
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.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
TypeSourceInfo * getTypeSourceInfo() const
Returns the declarator information for a base class or delegating initializer.
void printTerminator(raw_ostream &OS, const LangOptions &LO) const
printTerminator - A simple pretty printer of the terminator of a CFGBlock.
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)
ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State)
Updates the given ProgramState.
bool isReferenceType() const
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred)
bool isAllEnumCasesCovered() const
Returns true if the SwitchStmt is a switch of an enum value and all cases have been explicitly covere...
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...
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
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
void enableNodeReclamation(unsigned Interval)
Enable tracking of recently allocated nodes for potential reclamation when calling reclaimRecentlyAll...
static std::string getNodeAttributes(const ExplodedNode *N, void *)
static bool isRelationalOp(Opcode Opc)
SourceLocation getLocation() const
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val, const LocationContext *LCtx) override
Call PointerEscape callback when a value escapes as a result of bind.
static bool isLocType(QualType T)
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
ExplodedNodeSet::iterator iterator
This is a meta program point, which should be skipped by all the diagnostic reasoning etc...
static bool isEqualityOp(Opcode Opc)
ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx, ExplodedNode *Pred, unsigned maxVisitOnPath)
Updates the stack of loops contained by the ProgramState.
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
STATISTIC(NumRemoveDeadBindings, "The # of times RemoveDeadBindings is called")
const StackFrameContext * getCurrentStackFrame() const
const LocationContext * getLocationContext() const
ExplodedNode * generateCaseStmtNode(const iterator &I, ProgramStateRef State)
virtual bool inTopFrame() const
Return true if the current LocationContext has no caller context.
static bool isRecordType(QualType T)
const LocationContext * getParent() const
A builtin binary operation expression such as "x + y" or "x <= y".
const Stmt * getStmt() 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...
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, const ASTContext *Context=nullptr) const
const VarDecl * getVarDecl() const
bool shouldUnrollLoops()
Returns true if the analysis should try to unroll loops with known bounds.
const CXXBaseSpecifier * getBaseSpecifier() const
bool isAnyMemberInitializer() const
void ProcessStmt(const CFGStmt S, ExplodedNode *Pred)
An adjustment to be made to the temporary created when emitting a reference binding, which accesses a particular subobject of that temporary.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Represents binding an expression to a temporary.
virtual SVal getLValueField(const FieldDecl *D, SVal Base)
FieldDecl * getAnyMember() const
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
A default argument (C++ [dcl.fct.default]).
void processStaticInitializer(const DeclStmt *DS, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
Called by CoreEngine.
const CFGBlock * getCallSiteBlock() const
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.
CheckerManager & getCheckerManager() const
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
CXXCtorInitializer * getInitializer() 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
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const FieldDecl * getFieldDecl() const
const Stmt * getCallSite() const
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
bool isDelegatingInitializer() const
Determine whether this initializer is creating a delegating constructor.
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
CFGBlock - Represents a single basic block in a source-level CFG.
void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
bool hasDeadSymbols() const
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
InliningModes
The modes of inlining, which override the default analysis-wide settings.
const RegionTy * getAs() const
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.
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.
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
const FunctionProtoType * T
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
const Expr * getCondition() 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.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
This is the simplest builder which generates nodes in the ExplodedGraph.
void Add(ExplodedNode *N)
The pointer has been passed to a function call directly.
std::pair< const CXXBindTemporaryExpr *, const StackFrameContext * > CXXBindTemporaryContext
virtual StringRef getTagDescription() const =0
QualType getConditionType() const
const LocationContext * getLocationContext() const
bool isTemporaryDtorsBranch() const
static void printLocation2(raw_ostream &Out, SourceLocation SLoc)
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.
const CFGBlock * getDst() const
std::pair< const ProgramPointTag *, const ProgramPointTag * > geteagerlyAssumeBinOpBifurcationTags()
The reason for pointer escape is unknown.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
Traits for storing the call processing policy inside GDM.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;...
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for builtin atomic expressions.
This represents a Microsoft inline-assembly statement extension.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
const SwitchStmt * getSwitch() const
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.
Expr * getTrueExpr() const
CFGBaseDtor - Represents C++ object destructor implicitly generated for base object in destructor...
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
QualType getDestroyedType() const
Retrieve the type being destroyed.
const Expr * getSubExpr() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
reverse_iterator rbegin()
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper &SymReaper)=0
Scan all symbols referenced by the constraints.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
const MemRegion * getRegion() const
Get the underlining region.
ExplodedNode * generateNode(const iterator &I, ProgramStateRef State, bool isSink=false)
While alive, includes the current analysis stack in a crash trace.
void processEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, const ReturnStmt *RS=nullptr) override
Called by CoreEngine.
const MemRegion * StripCasts(bool StripBaseCasts=true) const
static const Stmt * ResolveCondition(const Stmt *Condition, const CFGBlock *B)
CFGTerminator getTerminator()
void processCFGElement(const CFGElement E, ExplodedNode *Pred, unsigned StmtIdx, NodeBuilderContext *Ctx) override
processCFGElement - Called by CoreEngine.
ProgramStateRef getInitialState(const LocationContext *InitLoc)
const LocationContext * getLocationContext() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
const Stmt * getStmt() const
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
const Stmt * getLoopStmt() const
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...
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
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 ...
const MemRegion * getAsRegion() const
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)
static void printLocation(raw_ostream &Out, SourceLocation SLoc)
void processIndirectGoto(IndirectGotoNodeBuilder &builder) override
processIndirectGoto - Called by CoreEngine.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
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.
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
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.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
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>, and corresponding __opencl_atomic_* for OpenCL 2.0.
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
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.
A class responsible for cleaning up unused symbols.
const Decl * getDecl() const
static bool isLogicalOp(Opcode Opc)
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
bool isVectorType() const
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
void insert(const ExplodedNodeSet &S)
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
StringRef getName() const
Return the actual identifier string.
ast_type_traits::DynTypedNode Node
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
Dataflow Directional Tag Classes.
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.
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call) override
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store...
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
const NodeBuilderContext & getContext()
unsigned getGraphTrimInterval()
Returns how often nodes in the ExplodedGraph should be recycled to save memory.
bool hasWorkRemaining() const
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.
StmtClass getStmtClass() const
void reclaimRecentlyAllocatedNodes()
Reclaim "uninteresting" nodes created since the last time this method was called. ...
enum clang::SubobjectAdjustment::@36 Kind
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
const Decl * getSingleDecl() const
const ProgramPointTag * getTag() const
Represents symbolic expression.
DOTGraphTraits(bool isSimple=false)
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
Represents an abstract call to a function or method along a particular path.
ExprEngine(AnalysisManager &mgr, bool gcEnabled, SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn)
ProgramStateRef getState() const
const Stmt * getLoopStmt() const
ContextKind getKind() const
ProgramStateManager & getStateManager() override
const Decl * getDecl() const
const CXXDeleteExpr * getDeleteExpr() const
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.
unsigned getIntWidth(QualType T) const
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)
Run checkers for end of analysis.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
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)
unsigned getIndex() const
void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for ObjCAtSynchronizedStmts.
IndirectFieldDecl * getIndirectMember() const
const LocationContext * getLocationContext() const
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Base for LValueReferenceType and RValueReferenceType.
Represents a base class of a C++ class.
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...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
SourceManager & getSourceManager()
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.
const CXXNewExpr * getAllocatorExpr() const
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.
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...
ProgramStateRef getState() const
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...
const MemRegion * getBaseRegion() const
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.
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion *> ExplicitRegions, ArrayRef< const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call)
Run checkers for region changes.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
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...
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
const StackFrameContext * getStackFrame() const
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.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
ConstraintManager & getConstraintManager()
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
AnalysisDeclContext * getAnalysisDeclContext() const
bool isFeasible(bool branch)
const Expr * getCond() const
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.
SourceLocation getLocStart() const LLVM_READONLY
const Expr * getTarget() const
This class handles loading and caching of source files into memory.
CFGTemporaryDtor - Represents C++ object destructor implicitly generated at the end of full expressio...
Defines enum values for all the target-independent builtin functions.
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
bool isUnknownOrUndef() const
QualType getType() const
Return the type wrapped by this type source info.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
QualType getType() const
Retrieves the type of the base class.
Represents the point where a loop ends.