30 #include "llvm/ADT/Statistic.h"
31 #include "llvm/Support/SaveAndRestore.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");
185 const Expr *InitWithAdjustments,
186 const Expr *Result) {
192 SVal InitValWithAdjustments = State->getSVal(InitWithAdjustments, LC);
198 Result = InitWithAdjustments;
202 assert(!InitValWithAdjustments.
getAs<
Loc>() ||
236 CommaLHSs, Adjustments);
240 dyn_cast<MaterializeTemporaryExpr>(Result)) {
254 for (
auto I = Adjustments.rbegin(),
E = Adjustments.rend();
I !=
E; ++
I) {
265 State = State->bindDefault(Reg,
UnknownVal(), LC);
278 SVal InitVal = State->getSVal(Init, LC);
282 State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
285 if (InitValWithAdjustments.
isUnknown()) {
289 Result, LC, InitWithAdjustments->
getType(),
293 State->bindLoc(Reg.
castAs<
Loc>(), InitValWithAdjustments, LC,
false);
295 State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
301 State = State->BindExpr(Result, LC, Reg);
316 SVal cond,
bool assumption) {
333 const char *NL,
const char *Sep) {
344 currStmtIdx = StmtIdx;
398 const Stmt *ReferenceStmt,
400 const Stmt *DiagnosticStmt,
403 ReferenceStmt ==
nullptr || isa<ReturnStmt>(ReferenceStmt))
404 &&
"PostStmt is not generally supported by the SymbolReaper yet");
405 assert(LC &&
"Must pass the current (or expiring) LocationContext");
407 if (!DiagnosticStmt) {
408 DiagnosticStmt = ReferenceStmt;
409 assert(DiagnosticStmt &&
"Required for clearing a LocationContext");
412 NumRemoveDeadBindings++;
418 if (!ReferenceStmt) {
420 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
442 Bldr.
generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K);
449 DiagnosticStmt, *
this, K);
464 "Checkers are not allowed to modify the Environment as a part of "
465 "checkDeadSymbols processing.");
467 "Checkers are not allowed to modify the Store as a part of "
468 "checkDeadSymbols processing.");
474 Bldr.
generateNode(DiagnosticStmt, *
I, CleanedCheckerSt, &cleanupTag, K);
487 "Error evaluating statement");
494 CleanedStates.Add(Pred);
499 E = CleanedStates.end();
I !=
E; ++
I) {
502 Visit(currStmt, *
I, DstI);
516 "Error evaluating initializer");
522 cast<CXXConstructorDecl>(stackFrame->getDecl());
525 SVal thisVal = State->getSVal(svalBuilder.
getCXXThis(decl, stackFrame));
534 if (
auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) {
546 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
554 while ((ASE = dyn_cast<ArraySubscriptExpr>(Init)))
557 SVal LValue = State->getSVal(Init, stackFrame);
560 InitVal = State->getSVal(*LValueLoc);
570 InitVal = State->getSVal(BMI->
getInit(), stackFrame);
573 assert(Tmp.
size() == 1 &&
"have not generated any new nodes yet");
574 assert(*Tmp.
begin() == Pred &&
"have not generated any new nodes yet");
578 evalBind(Tmp, Init, Pred, FieldLoc, InitVal,
true, &PP);
619 llvm_unreachable(
"Unexpected dtor kind.");
656 const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
665 varType = cast<TypedValueRegion>(Region)->getValueType();
679 SVal ArgVal = State->getSVal(Arg, LCtx);
683 if (State->isNull(ArgVal).isConstrainedTrue()) {
691 Bldr.generateNode(PP, Pred->
getState(), Pred);
717 CurDtor->
getBody(),
true, Pred, Dst);
730 State->getLValue(Member, State->getSVal(ThisVal).castAs<
Loc>());
734 CurDtor->
getBody(),
false, Pred, Dst);
743 if (State->contains<InitializedTemporariesSet>(
747 State = State->remove<InitializedTemporariesSet>(
755 assert(CleanDtorState.
size() <= 1);
757 CleanDtorState.
empty() ? Pred : *CleanDtorState.
begin();
761 false, CleanPred, Dst);
771 if (Pred->
getState()->contains<InitializedTemporariesSet>(
794 if (!State->contains<InitializedTemporariesSet>(
795 std::make_pair(BTE,
Node->getStackFrame()))) {
800 State = State->add<InitializedTemporariesSet>(
801 std::make_pair(BTE,
Node->getStackFrame()));
811 "Error evaluating statement");
815 assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
819 case Expr::ObjCIndirectCopyRestoreExprClass:
820 case Stmt::CXXDependentScopeMemberExprClass:
821 case Stmt::CXXInheritedCtorInitExprClass:
822 case Stmt::CXXTryStmtClass:
823 case Stmt::CXXTypeidExprClass:
824 case Stmt::CXXUuidofExprClass:
825 case Stmt::CXXFoldExprClass:
826 case Stmt::MSPropertyRefExprClass:
827 case Stmt::MSPropertySubscriptExprClass:
828 case Stmt::CXXUnresolvedConstructExprClass:
829 case Stmt::DependentScopeDeclRefExprClass:
830 case Stmt::ArrayTypeTraitExprClass:
831 case Stmt::ExpressionTraitExprClass:
832 case Stmt::UnresolvedLookupExprClass:
833 case Stmt::UnresolvedMemberExprClass:
834 case Stmt::TypoExprClass:
835 case Stmt::CXXNoexceptExprClass:
836 case Stmt::PackExpansionExprClass:
837 case Stmt::SubstNonTypeTemplateParmPackExprClass:
838 case Stmt::FunctionParmPackExprClass:
839 case Stmt::CoroutineBodyStmtClass:
840 case Stmt::CoawaitExprClass:
841 case Stmt::DependentCoawaitExprClass:
842 case Stmt::CoreturnStmtClass:
843 case Stmt::CoyieldExprClass:
844 case Stmt::SEHTryStmtClass:
845 case Stmt::SEHExceptStmtClass:
846 case Stmt::SEHLeaveStmtClass:
847 case Stmt::SEHFinallyStmtClass:
848 case Stmt::OMPParallelDirectiveClass:
849 case Stmt::OMPSimdDirectiveClass:
850 case Stmt::OMPForDirectiveClass:
851 case Stmt::OMPForSimdDirectiveClass:
852 case Stmt::OMPSectionsDirectiveClass:
853 case Stmt::OMPSectionDirectiveClass:
854 case Stmt::OMPSingleDirectiveClass:
855 case Stmt::OMPMasterDirectiveClass:
856 case Stmt::OMPCriticalDirectiveClass:
857 case Stmt::OMPParallelForDirectiveClass:
858 case Stmt::OMPParallelForSimdDirectiveClass:
859 case Stmt::OMPParallelSectionsDirectiveClass:
860 case Stmt::OMPTaskDirectiveClass:
861 case Stmt::OMPTaskyieldDirectiveClass:
862 case Stmt::OMPBarrierDirectiveClass:
863 case Stmt::OMPTaskwaitDirectiveClass:
864 case Stmt::OMPTaskgroupDirectiveClass:
865 case Stmt::OMPFlushDirectiveClass:
866 case Stmt::OMPOrderedDirectiveClass:
867 case Stmt::OMPAtomicDirectiveClass:
868 case Stmt::OMPTargetDirectiveClass:
869 case Stmt::OMPTargetDataDirectiveClass:
870 case Stmt::OMPTargetEnterDataDirectiveClass:
871 case Stmt::OMPTargetExitDataDirectiveClass:
872 case Stmt::OMPTargetParallelDirectiveClass:
873 case Stmt::OMPTargetParallelForDirectiveClass:
874 case Stmt::OMPTargetUpdateDirectiveClass:
875 case Stmt::OMPTeamsDirectiveClass:
876 case Stmt::OMPCancellationPointDirectiveClass:
877 case Stmt::OMPCancelDirectiveClass:
878 case Stmt::OMPTaskLoopDirectiveClass:
879 case Stmt::OMPTaskLoopSimdDirectiveClass:
880 case Stmt::OMPDistributeDirectiveClass:
881 case Stmt::OMPDistributeParallelForDirectiveClass:
882 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
883 case Stmt::OMPDistributeSimdDirectiveClass:
884 case Stmt::OMPTargetParallelForSimdDirectiveClass:
885 case Stmt::OMPTargetSimdDirectiveClass:
886 case Stmt::OMPTeamsDistributeDirectiveClass:
887 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
888 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
889 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
890 case Stmt::OMPTargetTeamsDirectiveClass:
891 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
892 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
893 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
894 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
895 case Stmt::CapturedStmtClass:
902 case Stmt::ParenExprClass:
903 llvm_unreachable(
"ParenExprs already handled.");
904 case Stmt::GenericSelectionExprClass:
905 llvm_unreachable(
"GenericSelectionExprs already handled.");
908 case Stmt::BreakStmtClass:
909 case Stmt::CaseStmtClass:
910 case Stmt::CompoundStmtClass:
911 case Stmt::ContinueStmtClass:
912 case Stmt::CXXForRangeStmtClass:
913 case Stmt::DefaultStmtClass:
914 case Stmt::DoStmtClass:
915 case Stmt::ForStmtClass:
916 case Stmt::GotoStmtClass:
917 case Stmt::IfStmtClass:
918 case Stmt::IndirectGotoStmtClass:
919 case Stmt::LabelStmtClass:
921 case Stmt::NullStmtClass:
922 case Stmt::SwitchStmtClass:
923 case Stmt::WhileStmtClass:
924 case Expr::MSDependentExistsStmtClass:
925 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
927 case Stmt::ObjCSubscriptRefExprClass:
928 case Stmt::ObjCPropertyRefExprClass:
929 llvm_unreachable(
"These are handled by PseudoObjectExpr");
931 case Stmt::GNUNullExprClass: {
940 case Stmt::ObjCAtSynchronizedStmtClass:
946 case Stmt::ExprWithCleanupsClass:
950 case Stmt::CXXBindTemporaryExprClass: {
962 case Stmt::DesignatedInitExprClass:
963 case Stmt::DesignatedInitUpdateExprClass:
964 case Stmt::ArrayInitLoopExprClass:
965 case Stmt::ArrayInitIndexExprClass:
966 case Stmt::ExtVectorElementExprClass:
967 case Stmt::ImaginaryLiteralClass:
968 case Stmt::ObjCAtCatchStmtClass:
969 case Stmt::ObjCAtFinallyStmtClass:
970 case Stmt::ObjCAtTryStmtClass:
971 case Stmt::ObjCAutoreleasePoolStmtClass:
972 case Stmt::ObjCEncodeExprClass:
973 case Stmt::ObjCIsaExprClass:
974 case Stmt::ObjCProtocolExprClass:
975 case Stmt::ObjCSelectorExprClass:
976 case Stmt::ParenListExprClass:
977 case Stmt::ShuffleVectorExprClass:
978 case Stmt::ConvertVectorExprClass:
979 case Stmt::VAArgExprClass:
980 case Stmt::CUDAKernelCallExprClass:
981 case Stmt::OpaqueValueExprClass:
982 case Stmt::AsTypeExprClass:
987 case Stmt::PredefinedExprClass:
988 case Stmt::AddrLabelExprClass:
989 case Stmt::AttributedStmtClass:
990 case Stmt::IntegerLiteralClass:
991 case Stmt::CharacterLiteralClass:
992 case Stmt::ImplicitValueInitExprClass:
993 case Stmt::CXXScalarValueInitExprClass:
994 case Stmt::CXXBoolLiteralExprClass:
995 case Stmt::ObjCBoolLiteralExprClass:
996 case Stmt::ObjCAvailabilityCheckExprClass:
997 case Stmt::FloatingLiteralClass:
998 case Stmt::NoInitExprClass:
999 case Stmt::SizeOfPackExprClass:
1000 case Stmt::StringLiteralClass:
1001 case Stmt::ObjCStringLiteralClass:
1002 case Stmt::CXXPseudoDestructorExprClass:
1003 case Stmt::SubstNonTypeTemplateParmExprClass:
1004 case Stmt::CXXNullPtrLiteralExprClass:
1005 case Stmt::OMPArraySectionExprClass:
1006 case Stmt::TypeTraitExprClass: {
1015 case Stmt::CXXDefaultArgExprClass:
1016 case Stmt::CXXDefaultInitExprClass: {
1026 ArgE = DefE->getExpr();
1028 ArgE = DefE->getExpr();
1030 llvm_unreachable(
"unknown constant wrapper kind");
1032 bool IsTemporary =
false;
1034 dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
1035 ArgE = MTE->GetTemporaryExpr();
1047 State = State->BindExpr(S, LCtx, *ConstantVal);
1049 State = createTemporaryRegionIfNeeded(State, LCtx,
1061 case Stmt::CXXStdInitializerListExprClass:
1062 case Expr::ObjCArrayLiteralClass:
1063 case Expr::ObjCDictionaryLiteralClass:
1064 case Expr::ObjCBoxedExprClass: {
1073 const Expr *Ex = cast<Expr>(
S);
1092 case Stmt::ArraySubscriptExprClass:
1098 case Stmt::GCCAsmStmtClass:
1104 case Stmt::MSAsmStmtClass:
1110 case Stmt::BlockExprClass:
1116 case Stmt::LambdaExprClass:
1127 case Stmt::BinaryOperatorClass: {
1139 state->getSVal(B->
getRHS(),
1159 case Stmt::CXXOperatorCallExprClass: {
1165 if (
const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
1166 if (MD->isInstance()) {
1170 createTemporaryRegionIfNeeded(State, LCtx, OCE->
getArg(0));
1171 if (NewState != State) {
1183 case Stmt::CallExprClass:
1184 case Stmt::CXXMemberCallExprClass:
1185 case Stmt::UserDefinedLiteralClass: {
1192 case Stmt::CXXCatchStmtClass: {
1199 case Stmt::CXXTemporaryObjectExprClass:
1200 case Stmt::CXXConstructExprClass: {
1207 case Stmt::CXXNewExprClass: {
1216 case Stmt::CXXDeleteExprClass: {
1223 e = PreVisit.
end(); i != e ; ++i)
1232 case Stmt::ChooseExprClass: {
1240 case Stmt::CompoundAssignOperatorClass:
1246 case Stmt::CompoundLiteralExprClass:
1252 case Stmt::BinaryConditionalOperatorClass:
1253 case Stmt::ConditionalOperatorClass: {
1256 = cast<AbstractConditionalOperator>(
S);
1262 case Stmt::CXXThisExprClass:
1268 case Stmt::DeclRefExprClass: {
1276 case Stmt::DeclStmtClass:
1282 case Stmt::ImplicitCastExprClass:
1283 case Stmt::CStyleCastExprClass:
1284 case Stmt::CXXStaticCastExprClass:
1285 case Stmt::CXXDynamicCastExprClass:
1286 case Stmt::CXXReinterpretCastExprClass:
1287 case Stmt::CXXConstCastExprClass:
1288 case Stmt::CXXFunctionalCastExprClass:
1289 case Stmt::ObjCBridgedCastExprClass: {
1301 case Expr::MaterializeTemporaryExprClass: {
1308 e = dstPrevisit.end(); i != e ; ++i) {
1316 case Stmt::InitListExprClass:
1322 case Stmt::MemberExprClass:
1328 case Stmt::AtomicExprClass:
1334 case Stmt::ObjCIvarRefExprClass:
1340 case Stmt::ObjCForCollectionStmtClass:
1346 case Stmt::ObjCMessageExprClass:
1352 case Stmt::ObjCAtThrowStmtClass:
1353 case Stmt::CXXThrowExprClass:
1359 case Stmt::ReturnStmtClass:
1365 case Stmt::OffsetOfExprClass:
1371 case Stmt::UnaryExprOrTypeTraitExprClass:
1378 case Stmt::StmtExprClass: {
1384 &&
"Empty statement expression must have void type.");
1392 state->getSVal(LastExpr,
1398 case Stmt::UnaryOperatorClass: {
1412 case Stmt::PseudoObjectExprClass: {
1432 bool ExprEngine::replayWithoutInlining(
ExplodedNode *N,
1436 assert(CalleeSF && CallerSF);
1443 BeforeProcessingCall = N;
1458 if (SP->getStmt() == CE)
1463 if (!BeforeProcessingCall)
1491 NumTimesRetriedWithoutInlining++;
1508 (isa<ForStmt>(Term) || isa<WhileStmt>(Term) || isa<DoStmt>(Term))))
1529 (*G.
roots_begin())->getLocation().getLocationContext();
1538 replayWithoutInlining(Pred, CalleeLC)))
1540 NumMaxBlockCountReachedInInlined++;
1542 NumMaxBlockCountReached++;
1545 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
1560 const Stmt *Condition,
1564 const Expr *Ex = dyn_cast<
Expr>(Condition);
1569 bool bitsInit =
false;
1571 while (
const CastExpr *CE = dyn_cast<CastExpr>(Ex)) {
1578 if (!bitsInit || newBits < bits) {
1583 Ex = CE->getSubExpr();
1593 return state->getSVal(Ex, LCtx);
1625 if (
const Expr *Ex = dyn_cast<Expr>(Condition))
1626 Condition = Ex->IgnoreParens();
1633 "Temporary destructor branches handled by processBindTemporary.");
1644 for (; I !=
E; ++
I) {
1649 const Stmt *LastStmt = CS->getStmt();
1653 llvm_unreachable(
"could not resolve condition");
1662 assert((!Condition || !isa<CXXBindTemporaryExpr>(Condition)) &&
1663 "CXXBindTemporaryExprs are handled by processBindTemporary.");
1666 currBldrCtx = &BldCtx;
1676 if (
const Expr *Ex = dyn_cast<Expr>(Condition))
1677 Condition = Ex->IgnoreParens();
1682 "Error evaluating branch");
1688 if (CheckersOutSet.empty())
1693 E = CheckersOutSet.end();
E !=
I; ++
I) {
1704 if (
const Expr *Ex = dyn_cast<Expr>(Condition)) {
1705 if (Ex->getType()->isIntegralOrEnumerationType()) {
1711 PrevState, Condition,
1732 std::tie(StTrue, StFalse) = PrevState->assume(V);
1750 currBldrCtx =
nullptr;
1765 currBldrCtx = &BuilderCtx;
1767 const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
1769 bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
1773 state = state->add<InitializedGlobalsSet>(VD);
1776 builder.generateNode(state, initHasRun, Pred);
1777 builder.markInfeasible(!initHasRun);
1779 currBldrCtx =
nullptr;
1801 for (iterator
I = builder.
begin(),
E = builder.
end();
I !=
E; ++
I) {
1802 if (
I.getLabel() == L) {
1808 llvm_unreachable(
"No block with label.");
1822 for (iterator
I=builder.
begin(),
E=builder.
end();
I !=
E; ++
I)
1827 static bool stackFrameDoesNotContainInitializedTemporaries(
ExplodedNode &Pred) {
1830 Pred.
getState()->get<InitializedTemporariesSet>();
1831 return std::find_if(Set.begin(), Set.end(),
1833 if (Ctx.second == Frame) {
1835 llvm::errs() <<
"\n";
1837 return Ctx.second == Frame;
1869 E = AfterRemovedDead.
end();
I !=
E; ++
I) {
1887 if (CondV_untested.
isUndef()) {
1898 iterator
I = builder.
begin(), EI = builder.
end();
1899 bool defaultIsFeasible = I == EI;
1901 for ( ; I != EI; ++
I) {
1906 const CaseStmt *Case = I.getCase();
1921 std::tie(StateCase, DefaultSt) =
1922 DefaultSt->assumeInclusiveRange(*NL, V1, V2);
1924 StateCase = DefaultSt;
1932 defaultIsFeasible =
true;
1934 defaultIsFeasible =
false;
1939 if (!defaultIsFeasible)
1971 if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
1974 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
1976 const Decl *D = LocCtxt->getDecl();
1978 const auto *DeclRefEx = dyn_cast<
DeclRefExpr>(Ex);
1982 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
1983 MD->getParent()->isLambda()) {
1986 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
1989 const FieldDecl *FD = LambdaCaptureFields[VD];
1993 assert(VD->getType().isConstQualified());
1994 V = state->getLValue(VD, LocCtxt);
1995 IsReference =
false;
1998 svalBuilder.
getCXXThis(MD, LocCtxt->getCurrentStackFrame());
1999 SVal CXXThisVal = state->getSVal(CXXThis);
2000 V = state->getLValue(FD, CXXThisVal);
2004 V = state->getLValue(VD, LocCtxt);
2005 IsReference = VD->getType()->isReferenceType();
2011 if (
const MemRegion *R = V.getAsRegion())
2012 V = state->getSVal(R);
2017 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
2024 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V));
2027 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
2029 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
2033 if (isa<FieldDecl>(D)) {
2040 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V),
nullptr,
2045 llvm_unreachable(
"Support for this Decl not implemented.");
2065 for (
auto *
Node : CheckerPreStmt) {
2069 state->getSVal(Idx, LCtx),
2070 state->getSVal(Base, LCtx));
2091 if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
2108 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
2109 if (MD->isInstance())
2110 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2113 state = state->BindExpr(M, LCtx, MDVal);
2120 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
2121 SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
2123 FieldDecl *field = cast<FieldDecl>(Member);
2124 SVal L = state->getLValue(field, baseExprVal);
2135 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
2136 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
2141 if (
const MemRegion *R = L.getAsRegion())
2142 L = state->getSVal(R);
2147 Bldr.
generateNode(M, *
I, state->BindExpr(M, LCtx, L),
nullptr,
2177 for (
unsigned SI = 0, Count = AE->
getNumSubExprs(); SI != Count; SI++) {
2179 SVal SubExprVal = State->getSVal(SubExpr, LCtx);
2180 ValuesToInvalidate.push_back(SubExprVal);
2183 State = State->invalidateRegions(ValuesToInvalidate, AE,
2190 State = State->BindExpr(AE, LCtx, ResultVal);
2199 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
2206 bool VisitSymbol(
SymbolRef Sym)
override {
2207 Symbols.insert(Sym);
2223 bool escapes =
true;
2227 escapes = !regionLoc->getRegion()->hasStackStorage();
2235 SVal StoredVal = State->getSVal(regionLoc->getRegion());
2236 if (StoredVal != Val)
2237 escapes = (State == (State->bindLoc(*regionLoc, Val, LCtx)));
2249 CollectReachableSymbolsCallback Scanner =
2250 State->scanReachableSymbols<CollectReachableSymbolsCallback>(Val);
2269 if (!Invalidated || Invalidated->empty())
2283 E = ExplicitRegions.end();
I !=
E; ++
I) {
2285 SymbolsDirectlyInvalidated.insert(R->getSymbol());
2289 for (InvalidatedSymbols::const_iterator
I=Invalidated->begin(),
2290 E = Invalidated->end();
I!=
E; ++
I) {
2292 if (SymbolsDirectlyInvalidated.count(sym))
2294 SymbolsIndirectlyInvalidated.insert(sym);
2297 if (!SymbolsDirectlyInvalidated.empty())
2302 if (!SymbolsIndirectlyInvalidated.empty())
2324 StoreE, *
this, *PP);
2349 state = state->bindLoc(location.
castAs<
Loc>(),
2350 Val, LC, !atDeclInit);
2355 LocReg = LocRegVal->getRegion();
2372 const Expr *LocationE,
2378 const Expr *StoreE = AssignE ? AssignE : LocationE;
2382 evalLocation(Tmp, AssignE, LocationE, Pred, state, location, tag,
false);
2391 evalBind(Dst, StoreE, *NI, location, Val,
false);
2396 const Expr *BoundEx,
2403 assert(!location.
getAs<
NonLoc>() &&
"location cannot be a NonLoc.");
2409 dyn_cast_or_null<TypedValueRegion>(location.
getAsRegion())) {
2414 loadReferenceTag(TagProviderName,
"Load Reference");
2416 evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state,
2417 location, &loadReferenceTag,
2418 getContext().getPointerType(RT->getPointeeType()));
2422 state = (*I)->getState();
2423 location = state->getSVal(BoundEx, (*I)->getLocationContext());
2424 evalLoadCommon(Dst, NodeEx, BoundEx, *
I, state, location, tag, LoadTy);
2430 evalLoadCommon(Dst, NodeEx, BoundEx, Pred, state, location, tag, LoadTy);
2435 const Expr *BoundEx,
2445 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location, tag,
true);
2455 state = (*NI)->getState();
2462 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
2465 Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag,
2472 const Stmt *BoundEx,
2485 BldrTop.takeNodes(Pred);
2498 Bldr.generateNode(NodeEx, Pred, state, &tag);
2502 NodeEx, BoundEx, *
this);
2503 BldrTop.addNodes(Tmp);
2506 std::pair<const ProgramPointTag *, const ProgramPointTag*>
2509 eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
2510 "Eagerly Assume True"),
2511 eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
2512 "Eagerly Assume False");
2513 return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
2514 &eagerlyAssumeBinOpBifurcationFalse);
2535 if (SEV && SEV->isExpression()) {
2536 const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
2540 std::tie(StateTrue, StateFalse) = state->assume(*SEV);
2629 llvm::raw_string_ostream Out(sbuf);
2636 Out <<
"Block Entrance: B"
2650 Out <<
"CallExitBegin";
2654 Out <<
"CallExitEnd";
2658 Out <<
"PostStmtPurgeDeadSymbols";
2662 Out <<
"PreStmtPurgeDeadSymbols";
2666 Out <<
"Epsilon Point";
2681 Out <<
"PostCall: ";
2690 Out <<
"PostInitializer: ";
2712 Out <<
"\\|Terminator: ";
2723 if (isa<SwitchStmt>(T)) {
2727 if (
const CaseStmt *
C = dyn_cast<CaseStmt>(Label)) {
2733 if (
const Stmt *RHS =
C->getRHS()) {
2741 assert (isa<DefaultStmt>(Label));
2742 Out <<
"\\ldefault:";
2746 Out <<
"\\l(implicit) default:";
2748 else if (isa<IndirectGotoStmt>(T)) {
2752 Out <<
"\\lCondition: ";
2767 assert(S !=
nullptr &&
"Expecting non-null Stmt");
2775 Out <<
"\\lPreStmt\\l;";
2777 Out <<
"\\lPostLoad\\l;";
2779 Out <<
"\\lPostStore\\l";
2781 Out <<
"\\lPostLValue\\l";
2788 Out <<
"\\|StateID: " << (
const void*) state.get()
2789 <<
" NodeID: " << (
const void*) N <<
"\\|";
2792 Out <<
"Location context stack (from current to outer):\\l";
2795 for (; LC; LC = LC->
getParent(), ++Idx) {
2796 Out << Idx <<
". (" << (
const void *)LC <<
") ";
2800 Out <<
"Calling " << D->getQualifiedNameAsString();
2802 Out <<
"Calling anonymous code";
2803 if (
const Stmt *
S = cast<StackFrameContext>(LC)->getCallSite()) {
2805 printLocation2(Out,
S->getLocStart());
2809 Out <<
"Invoking block";
2810 if (
const Decl *D = cast<BlockInvocationContext>(LC)->getBlockDecl()) {
2811 Out <<
" defined at ";
2812 printLocation2(Out, D->getLocStart());
2816 Out <<
"Entering scope";
2824 state->printDOT(Out);
2841 std::vector<const ExplodedNode*> Src;
2846 const_cast<BugType*>(*I)->FlushReports(BR);
2852 if (N) Src.push_back(N);
2874 std::unique_ptr<ExplodedGraph> TrimmedG(G.
trim(Nodes));
2876 if (!TrimmedG.get())
2877 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
2879 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.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0) const
CFGNewAllocator - Represents C++ allocator call.
StmtClass getStmtClass() const
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.
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const LocationContext *LCtx)
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.
Stmt - This represents one statement.
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...
unsigned getIntWidth(QualType T) const
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.
virtual QualType getValueType() const =0
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...
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
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()
const MemRegion * getBaseRegion() 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.
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
BoundNodesTreeBuilder Nodes
void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
const Expr * getTarget() const
void runCheckersForLocation(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, bool isLoad, const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &Eng)
Run checkers for load/store of a location.
const SwitchStmt * getSwitch() const
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
One of these records is kept for each identifier that is lexed.
ImplTy::iterator iterator
A pointer escapes due to binding its value to a location that the analyzer cannot track...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
bool isReferenceType() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Represents a program point after a store evaluation.
CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated for automatic object or t...
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst)
MemRegionManager & getRegionManager()
AnalysisDeclContext * getAnalysisDeclContext() const
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred)
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void EndPath(ProgramStateRef St)
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
unsigned eagerlyAssumeBinOpBifurcation
The flag regulates if we should eagerly assume evaluations of conditionals, thus, bifurcating the pat...
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
static std::string getNodeAttributes(const ExplodedNode *N, void *)
static bool isRelationalOp(Opcode Opc)
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)
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 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...
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...
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
DefinedSVal getFunctionPointer(const FunctionDecl *func)
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
bool isDelegatingInitializer() const
Determine whether this initializer is creating a delegating constructor.
void ProcessStmt(const CFGStmt S, ExplodedNode *Pred)
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...
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.
virtual SVal getLValueField(const FieldDecl *D, SVal Base)
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.
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...
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
InliningModes
The modes of inlining, which override the default analysis-wide settings.
SymbolicRegion - A special, "non-concrete" region.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
static unsigned getNumSubExprs(AtomicOp Op)
Determine the number of arguments the specified atomic builtin should have.
const CFGBlock * getDst() const
void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
void processSwitch(SwitchNodeBuilder &builder) override
ProcessSwitch - Called by CoreEngine.
void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L) override
Called by CoreEngine.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
const ProgramStateRef & getState() const
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
StringRef getName() const
Return the actual identifier string.
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
const Stmt * getStmt() const
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
Represents a C++ destructor within a class.
This is the simplest builder which generates nodes in the ExplodedGraph.
CXXCtorInitializer * getInitializer() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
The pointer has been passed to a function call directly.
std::pair< const CXXBindTemporaryExpr *, const StackFrameContext * > CXXBindTemporaryContext
virtual StringRef getTagDescription() const =0
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
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.
std::pair< const ProgramPointTag *, const ProgramPointTag * > geteagerlyAssumeBinOpBifurcationTags()
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
The reason for pointer escape is unknown.
bool isIndirectMemberInitializer() const
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type...
Traits for storing the call processing policy inside GDM.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
const LocationContext * getLocationContext() const
unsigned getBlockID() const
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.
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
Scan all symbols referenced by the constraints.
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.
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.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
static const Stmt * ResolveCondition(const Stmt *Condition, const CFGBlock *B)
bool isConsumedExpr(Expr *E) const
CFGTerminator getTerminator()
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 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.
void print(raw_ostream &OS, const SourceManager &SM) const
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 StackFrameContext * getCurrentStackFrame() const
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
FieldDecl * getAnyMember() const
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
ProgramPoints can be "tagged" as representing points specific to a given analysis entity...
AnalysisManager & getAnalysisManager() override
void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex)
evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic expressions of ...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
LabelDecl - Represents the declaration of a label.
ExplodedNode * generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
const Expr * getCond() const
bool isTemporaryDtorsBranch() const
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
static void printLocation(raw_ostream &Out, SourceLocation SLoc)
void processIndirectGoto(IndirectGotoNodeBuilder &builder) override
processIndirectGoto - Called by CoreEngine.
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
SourceLocation getLocStart() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
BugTypesTy::iterator iterator
Iterator over the set of BugTypes tracked by the BugReporter.
const Stmt * getStmt() const
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
void processBranch(const Stmt *Condition, const Stmt *Term, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) override
ProcessBranch - Called by CoreEngine.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>.
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
AnalyzerOptions & options
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitObjCForCollectionStmt - Transfer function logic for ObjCForCollectionStmt.
const Decl * getDecl() const
A class responsible for cleaning up unused symbols.
bool isAllEnumCasesCovered() const
Returns true if the SwitchStmt is a switch of an enum value and all cases have been explicitly covere...
void getCaptureFields(llvm::DenseMap< const VarDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
static bool isLogicalOp(Opcode Opc)
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
QualType getType() const
Return the type wrapped by this type source info.
void insert(const ExplodedNodeSet &S)
unsigned maxBlockVisitOnPath
The maximum number of times the analyzer visits a block.
std::unique_ptr< ExplodedGraph > trim(ArrayRef< const NodeTy * > Nodes, InterExplodedGraphMap *ForwardMap=nullptr, InterExplodedGraphMap *InverseMap=nullptr) const
Creates a trimmed version of the graph that only contains paths leading to the given nodes...
ast_type_traits::DynTypedNode Node
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
TypeSourceInfo * getTypeSourceInfo() const
Returns the declarator information for a base class or delegating initializer.
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
const LocationContext * getParent() const
ExplodedNode * generateDefaultCaseNode(ProgramStateRef State, bool isSink=false)
SValBuilder & getSValBuilder()
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
void addNodes(const ExplodedNodeSet &S)
StoreManager & getStoreManager()
Represents a program point just after an implicit call event.
const LocationContext * getLocationContext() const
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
const NodeBuilderContext & getContext()
This node builder keeps track of the generated sink nodes.
bool isPurgeKind()
Is this a program point corresponding to purge/removal of dead symbols and bindings.
void reclaimRecentlyAllocatedNodes()
Reclaim "uninteresting" nodes created since the last time this method was called. ...
SourceLocation getLocation() const
enum clang::SubobjectAdjustment::@36 Kind
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
ContextKind getKind() const
const T * getAs() const
Member-template getAs<specific type>'.
Expr * getFalseExpr() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Represents a C++ base or member initializer.
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for ObjCAtSynchronizedStmts.
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
EQClasses_iterator EQClasses_end()
Base for LValueReferenceType and RValueReferenceType.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Represents a base class of a C++ class.
bool isAnyMemberInitializer() const
SourceManager & getSourceManager()
void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block)
Inform the CoreEngine that a basic block was aborted because it could not be completely analyzed...
const StackFrameContext * getStackFrame() const
void enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS)
enqueue the nodes corresponding to the end of function onto the end of path / work list...
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.
Represents a C++ struct/union/class.
reverse_body_iterator body_rbegin()
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
CFGImplicitDtor - Represents C++ object destructor implicitly generated by compiler on various occasi...
Optional< SVal > getConstantVal(const Expr *E)
Returns the value of E, if it can be determined in a non-path-sensitive manner.
pred_iterator pred_begin()
ExplodedNode * generateNode(ProgramStateRef State, bool branch, ExplodedNode *Pred)
CFGElement - Represents a top-level expression in a basic block.
This class is used for builtin types like 'int'.
ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption) override
evalAssume - Callback function invoked by the ConstraintManager when making assumptions about state v...
CFGMemberDtor - Represents C++ object destructor implicitly generated for member object in destructor...
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
void processEndWorklist(bool hasWorkRemaining) override
Called by CoreEngine when the analysis worklist has terminated.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
const LangOptions & getLangOpts() const
A reference to a declared variable, function, enum, etc.
static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const CFGStmt S, const ExplodedNode *Pred, const LocationContext *LC)
CFGInitializer - Represents C++ base or member initializer from constructor's initialization list...
const Expr * getSubExpr() const
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
bool mayInlineCXXAllocator()
Returns whether or not allocator call may be considered for inlining.
void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for member expressions.
ParentMap & getParentMap()
AnalysisPurgeMode AnalysisPurgeOpt
NamedDecl - This represents a decl with a name.
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
ConstraintManager & getConstraintManager()
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
const CXXBaseSpecifier * getBaseSpecifier() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool isFeasible(bool branch)
const char * getStmtClassName() const
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.
SourceLocation getLocStart() const LLVM_READONLY
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.