64#include "llvm/ADT/APSInt.h"
65#include "llvm/ADT/DenseMap.h"
66#include "llvm/ADT/ImmutableMap.h"
67#include "llvm/ADT/ImmutableSet.h"
68#include "llvm/ADT/STLExtras.h"
69#include "llvm/ADT/SmallVector.h"
70#include "llvm/Support/Casting.h"
71#include "llvm/Support/Compiler.h"
72#include "llvm/Support/DOTGraphTraits.h"
73#include "llvm/Support/ErrorHandling.h"
74#include "llvm/Support/GraphWriter.h"
75#include "llvm/Support/IOSandbox.h"
76#include "llvm/Support/TimeProfiler.h"
77#include "llvm/Support/raw_ostream.h"
90#define DEBUG_TYPE "ExprEngine"
93 "The # of times RemoveDeadBindings is called");
95 NumMaxBlockCountReached,
96 "The # of aborted paths due to reaching the maximum block count in "
97 "a top level function");
99 NumMaxBlockCountReachedInInlined,
100 "The # of aborted paths due to reaching the maximum block count in "
101 "an inlined function");
103 "The # of times we re-evaluated a call without inlining");
124class ConstructedObjectKey {
125 using ConstructedObjectKeyImpl =
126 std::pair<ConstructionContextItem, const StackFrame *>;
127 const ConstructedObjectKeyImpl Impl;
134 const ConstructionContextItem &getItem()
const {
return Impl.first; }
135 const StackFrame *getStackFrame()
const {
return Impl.second; }
137 ASTContext &getASTContext()
const {
138 return getStackFrame()->getDecl()->getASTContext();
141 void printJson(llvm::raw_ostream &Out, PrinterHelper *Helper,
142 PrintingPolicy &PP)
const {
143 const Stmt *S = getItem().getStmtOrNull();
144 const CXXCtorInitializer *I =
nullptr;
146 I = getItem().getCXXCtorInitializer();
149 Out <<
"\"stmt_id\": " << S->
getID(getASTContext());
151 Out <<
"\"init_id\": " << I->
getID(getASTContext());
154 Out <<
", \"kind\": \"" << getItem().getKindAsString()
155 <<
"\", \"argument_index\": ";
158 Out << getItem().getIndex();
163 Out <<
", \"pretty\": ";
172 void Profile(llvm::FoldingSetNodeID &ID)
const {
174 ID.AddPointer(Impl.second);
177 bool operator==(
const ConstructedObjectKey &RHS)
const {
178 return Impl == RHS.Impl;
181 bool operator<(
const ConstructedObjectKey &RHS)
const {
182 return Impl < RHS.Impl;
187typedef llvm::ImmutableMap<ConstructedObjectKey, SVal>
198typedef llvm::ImmutableMap<
199 std::pair<const CXXConstructExpr *, const StackFrame *>,
unsigned>
200 IndexOfElementToConstructMap;
202 IndexOfElementToConstructMap)
207typedef llvm::ImmutableMap<
208 std::pair<const CXXConstructExpr *, const StackFrame *>,
unsigned>
212typedef llvm::ImmutableMap<const StackFrame *, unsigned>
221static const char* TagProviderName =
"ExprEngine";
226 : CTU(CTU), IsCTUEnabled(mgr.getAnalyzerOptions().IsNaiveCTUEnabled),
228 Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.
getGraph()),
229 StateMgr(
getContext(), mgr.getStoreManagerCreator(),
230 mgr.getConstraintManagerCreator(), G.getAllocator(), this),
232 svalBuilder(StateMgr.
getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
233 BR(mgr, *this), VisitedCallees(VisitedCalleesIn),
234 HowToInline(HowToInlineIn) {
235 unsigned TrimInterval = mgr.
options.GraphTrimInterval;
236 if (TrimInterval != 0) {
238 G.enableNodeReclamation(TrimInterval);
254 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
258 if (!II || !(II->
getName() ==
"main" && FD->getNumParams() > 0))
263 const auto *BT = dyn_cast<BuiltinType>(T);
264 if (!BT || !BT->isInteger())
267 const MemRegion *R = state->getRegion(PD, InitSF);
273 svalBuilder.makeZeroVal(T),
274 svalBuilder.getConditionType());
276 std::optional<DefinedOrUnknownSVal> Constraint =
289 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
293 const MemRegion *R = state->getRegion(SelfD, InitSF);
296 if (std::optional<Loc> LV =
V.getAs<
Loc>()) {
298 state = state->assume(*LV,
true);
299 assert(state &&
"'self' cannot be null");
303 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
304 if (MD->isImplicitObjectMemberFunction()) {
311 SVal V = state->getSVal(L);
312 if (std::optional<Loc> LV =
V.getAs<
Loc>()) {
313 state = state->assume(*LV,
true);
314 assert(state &&
"'this' cannot be null");
326 const SubRegion **OutRegionWithAdjustments) {
332 SVal InitValWithAdjustments = State->getSVal(InitWithAdjustments, SF);
337 if (OutRegionWithAdjustments)
338 *OutRegionWithAdjustments =
nullptr;
341 Result = InitWithAdjustments;
345 assert(!
isa<Loc>(InitValWithAdjustments) ||
347 Result->getType()->isMemberPointerType());
350 ProgramStateManager &StateMgr = State->getStateManager();
351 MemRegionManager &MRMgr = StateMgr.getRegionManager();
352 StoreManager &StoreMgr = StateMgr.getStoreManager();
375 SmallVector<const Expr *, 2> CommaLHSs;
376 SmallVector<SubobjectAdjustment, 2> Adjustments;
379 CommaLHSs, Adjustments);
386 const TypedValueRegion *TR =
nullptr;
387 if (
const auto *MT = dyn_cast<MaterializeTemporaryExpr>(
Result)) {
389 State = finishObjectConstruction(State, MT, SF);
390 State = State->BindExpr(
Result, SF, *
V);
392 }
else if (
const ValueDecl *VD = MT->getExtendingDecl()) {
398 TR = MRMgr.getCXXStaticLifetimeExtendedObjectRegion(
Init, VD);
400 TR = MRMgr.getCXXLifetimeExtendedObjectRegion(
Init, VD, SF);
404 TR = MRMgr.getCXXTempObjectRegion(
Init, SF);
407 TR = MRMgr.getCXXTempObjectRegion(
Init, SF);
410 SVal Reg = loc::MemRegionVal(TR);
414 for (
const SubobjectAdjustment &Adj : llvm::reverse(Adjustments)) {
426 nullptr,
nullptr,
nullptr);
439 SVal InitVal = State->getSVal(
Init, SF);
443 State = State->bindLoc(BaseReg.
castAs<Loc>(), InitVal, SF,
false);
447 if (InitValWithAdjustments.
isUnknown()) {
455 State->bindLoc(Reg.
castAs<Loc>(), InitValWithAdjustments, SF,
false);
457 State = State->bindLoc(BaseReg.
castAs<Loc>(), InitVal, SF,
false);
463 if (
Result->isGLValue()) {
464 State = State->BindExpr(
Result, SF, Reg);
466 State = State->BindExpr(
Result, SF, InitValWithAdjustments);
472 if (OutRegionWithAdjustments)
479 const CXXConstructExpr *E,
480 const StackFrame *SF,
unsigned Idx) {
481 auto Key = std::make_pair(E, SF);
483 assert(!State->contains<IndexOfElementToConstruct>(Key) || Idx > 0);
485 return State->set<IndexOfElementToConstruct>(Key, Idx);
488std::optional<unsigned>
491 const unsigned *
V = State->get<PendingInitLoop>({E, SF});
492 return V ? std::make_optional(*
V) : std::nullopt;
498 auto Key = std::make_pair(E, SF);
500 assert(E && State->contains<PendingInitLoop>(Key));
501 return State->remove<PendingInitLoop>(Key);
508 auto Key = std::make_pair(E, SF);
510 assert(!State->contains<PendingInitLoop>(Key) && Size > 0);
512 return State->set<PendingInitLoop>(Key, Size);
517 const unsigned *
V = State->get<IndexOfElementToConstruct>({E, SF});
518 return V ? std::make_optional(*
V) : std::nullopt;
523 auto Key = std::make_pair(E, SF);
525 assert(E && State->contains<IndexOfElementToConstruct>(Key));
526 return State->remove<IndexOfElementToConstruct>(Key);
529std::optional<unsigned>
532 assert(SF &&
"StackFrame shouldn't be null!");
534 const unsigned *
V = State->get<PendingArrayDestruction>(SF);
535 return V ? std::make_optional(*
V) : std::nullopt;
541 assert(SF &&
"StackFrame shouldn't be null!");
542 return State->set<PendingArrayDestruction>(SF, Idx);
548 assert(SF &&
"StackFrame shouldn't be null!");
549 assert(State->contains<PendingArrayDestruction>(SF));
550 return State->remove<PendingArrayDestruction>(SF);
557 ConstructedObjectKey Key(Item, SF);
561 if (
auto DS = dyn_cast_or_null<DeclStmt>(Item.
getStmtOrNull())) {
562 if (
auto VD = dyn_cast_or_null<VarDecl>(DS->getSingleDecl()))
563 Init = VD->getInit();
566 if (
auto LE = dyn_cast_or_null<LambdaExpr>(Item.
getStmtOrNull()))
575 if (
const auto *AILE = dyn_cast_or_null<ArrayInitLoopExpr>(
Init))
584 assert((!State->get<ObjectsUnderConstruction>(Key) ||
585 Key.getItem().getKind() ==
587 State->contains<IndexOfElementToConstruct>(
588 {dyn_cast_or_null<CXXConstructExpr>(Init), SF})) &&
589 "The object is already marked as `UnderConstruction`, when it's not "
591 return State->set<ObjectsUnderConstruction>(Key,
V);
598 ConstructedObjectKey Key(Item, SF);
599 const SVal *
V = State->get<ObjectsUnderConstruction>(Key);
600 return V ? std::make_optional(*
V) : std::nullopt;
607 ConstructedObjectKey Key(Item, SF);
608 assert(State->contains<ObjectsUnderConstruction>(Key));
609 return State->remove<ObjectsUnderConstruction>(Key);
615 ConstructedObjectKey Key({BTE,
true}, SF);
618 return State->set<ObjectsUnderConstruction>(Key,
UnknownVal());
623 const CXXBindTemporaryExpr *BTE,
624 const StackFrame *SF) {
625 ConstructedObjectKey Key({BTE,
true}, SF);
626 assert(State->contains<ObjectsUnderConstruction>(Key));
627 return State->remove<ObjectsUnderConstruction>(Key);
631 const CXXBindTemporaryExpr *BTE,
632 const StackFrame *SF) {
633 ConstructedObjectKey Key({BTE,
true}, SF);
634 return State->contains<ObjectsUnderConstruction>(Key);
638 const StackFrame *FromSF,
639 const StackFrame *ToSF) {
640 const StackFrame *SF = FromSF;
642 assert(SF &&
"ToSF must be a parent of FromSF!");
643 for (
auto I : State->get<ObjectsUnderConstruction>())
644 if (I.first.getStackFrame() == SF)
659 SVal cond,
bool assumption) {
668 state, invalidated, Explicits, Regions, SF,
Call);
674 unsigned int Space = 0,
bool IsDot =
false) {
679 bool HasItem =
false;
682 const ConstructedObjectKey *LastKey =
nullptr;
683 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
684 const ConstructedObjectKey &Key = I.first;
685 if (Key.getStackFrame() != SF)
696 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
697 const ConstructedObjectKey &Key = I.first;
699 if (Key.getStackFrame() != SF)
702 Indent(Out, Space, IsDot) <<
"{ ";
703 Key.printJson(Out,
nullptr, PP);
704 Out <<
", \"value\": \"" <<
Value <<
"\" }";
712 Indent(Out, --Space, IsDot) <<
']';
720 const StackFrame *SF,
unsigned int Space = 0,
bool IsDot =
false) {
721 using KeyT = std::pair<const Expr *, const StackFrame *>;
727 bool HasItem =
false;
731 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
732 const KeyT &Key = I.first;
733 if (Key.second != SF)
744 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
745 const KeyT &Key = I.first;
746 unsigned Value = I.second;
747 if (Key.second != SF)
750 Indent(Out, Space, IsDot) <<
"{ ";
753 const Expr *E = Key.first;
754 Out <<
"\"stmt_id\": " << E->
getID(Context);
757 Out <<
", \"kind\": null";
760 Out <<
", \"pretty\": ";
766 Out <<
", \"value\": \"Current index: " <<
Value - 1 <<
"\" }";
774 Indent(Out, --Space, IsDot) <<
']';
782 unsigned int Space = 0,
783 bool IsDot =
false) {
784 using KeyT = std::pair<const CXXConstructExpr *, const StackFrame *>;
790 bool HasItem =
false;
794 for (
const auto &I : State->get<PendingInitLoop>()) {
795 const KeyT &Key = I.first;
796 if (Key.second != SF)
807 for (
const auto &I : State->get<PendingInitLoop>()) {
808 const KeyT &Key = I.first;
809 unsigned Value = I.second;
810 if (Key.second != SF)
813 Indent(Out, Space, IsDot) <<
"{ ";
816 Out <<
"\"stmt_id\": " << E->
getID(Context);
818 Out <<
", \"kind\": null";
819 Out <<
", \"pretty\": ";
825 Out <<
", \"value\": \"Flattened size: " <<
Value <<
"\"}";
833 Indent(Out, --Space, IsDot) <<
']';
842 unsigned int Space = 0,
bool IsDot =
false) {
846 bool HasItem =
false;
849 KeyT LastKey =
nullptr;
850 for (
const auto &I : State->get<PendingArrayDestruction>()) {
851 const KeyT &Key = I.first;
863 for (
const auto &I : State->get<PendingArrayDestruction>()) {
864 const KeyT &Key = I.first;
868 Indent(Out, Space, IsDot) <<
"{ ";
870 Out <<
"\"stmt_id\": null";
871 Out <<
", \"kind\": null";
872 Out <<
", \"pretty\": \"Current index: \"";
873 Out <<
", \"value\": \"" << I.second <<
"\" }";
881 Indent(Out, --Space, IsDot) <<
']';
895template <
typename Trait,
typename Printer,
typename... Args>
898 const char *NL,
unsigned int Space,
bool IsDot,
899 const char *jsonPropertyName, Printer printer, Args &&...args) {
903 unsigned int,
bool, Args &&...);
907 static_assert(std::is_function_v<std::remove_pointer_t<Printer>>,
908 "Printer is not a function!");
909 static_assert(std::is_convertible_v<Printer, RequiredType>,
910 "Printer doesn't have the required type!");
912 if (SF && !State->get<Trait>().isEmpty()) {
913 Indent(Out, Space, IsDot) <<
'\"' << jsonPropertyName <<
"\": ";
917 printer(Out, State, NL, SF, Space, IsDot, std::forward<Args>(args)...);
921 Indent(Out, Space, IsDot) <<
"]," << NL;
927 unsigned int Space,
bool IsDot)
const {
930 Out, State, SF, NL, Space, IsDot,
"constructing_objects",
933 Out, State, SF, NL, Space, IsDot,
"index_of_element",
936 Out, State, SF, NL, Space, IsDot,
"pending_init_loops",
939 Out, State, SF, NL, Space, IsDot,
"pending_destructors",
954 currStmtIdx = StmtIdx;
1016 llvm::TimeTraceScope TimeScope(
"ExprEngine::removeDead");
1019 &&
"PostStmt is not generally supported by the SymbolReaper yet");
1020 assert(SF &&
"Must pass the current (or expiring) StackFrame");
1022 if (!DiagnosticStmt) {
1023 DiagnosticStmt = ReferenceStmt;
1024 assert(DiagnosticStmt &&
"Required for clearing a StackFrame");
1027 NumRemoveDeadBindings++;
1033 if (!ReferenceStmt) {
1035 "Use PostStmtPurgeDeadSymbolsKind for clearing a StackFrame");
1041 for (
auto I : CleanedState->get<ObjectsUnderConstruction>()) {
1042 if (
SymbolRef Sym = I.second.getAsSymbol())
1044 if (
const MemRegion *MR = I.second.getAsRegion())
1053 CleanedState = StateMgr.removeDeadBindingsFromEnvironmentAndStore(
1054 CleanedState, SF, SymReaper);
1061 DiagnosticStmt, *
this, K);
1071 for (
const auto I : CheckedSet) {
1078 assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->
getState()) &&
1079 "Checkers are not allowed to modify the Environment as a part of "
1080 "checkDeadSymbols processing.");
1081 assert(StateMgr.haveEqualStores(CheckerState, Pred->
getState()) &&
1082 "Checkers are not allowed to modify the Store as a part of "
1083 "checkDeadSymbols processing.");
1088 StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
1091 Out.insert(Engine.makeNode(L, CleanedCheckerSt, I));
1102 G.reclaimRecentlyAllocatedNodes();
1106 "Error evaluating statement");
1113 CleanedStates.
insert(Pred);
1117 for (
const auto I : CleanedStates) {
1120 Visit(currStmt, I, DstI);
1125 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1131 "Error evaluating end of the loop");
1134 if(AMgr.options.ShouldUnrollLoops)
1140 Engine.enqueueStmtNode(N,
getCurrBlock(), currStmtIdx);
1151 "Error evaluating initializer");
1157 SVal thisVal = State->getSVal(svalBuilder.getCXXThis(
decl, SF));
1169 State = finishObjectConstruction(State, BMI, SF);
1171 Tmp.
insert(Engine.makeNode(PS, State, Pred));
1179 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
1183 if (
Init->getType()->isArrayType()) {
1187 while ((ASE = dyn_cast<ArraySubscriptExpr>(
Init)))
1190 InitVal = State->getSVal(
Init, SF);
1199 InitVal = State->getSVal(BMI->
getInit(), SF);
1203 evalBind(Tmp,
Init, Pred, FieldLoc, InitVal,
true, &PP);
1211 SVal InitVal = State->getSVal(
Init, SF);
1212 evalBind(Tmp,
Init, Pred, BaseLoc, InitVal,
true);
1227 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1230std::pair<ProgramStateRef, uint64_t>
1231ExprEngine::prepareStateForArrayDestruction(
const ProgramStateRef State,
1235 SVal *ElementCountVal) {
1236 assert(Region !=
nullptr &&
"Not-null region expected");
1239 while (
const auto *NTy = dyn_cast<ArrayType>(Ty))
1240 Ty = NTy->getElementType().getDesugaredType(
getContext());
1244 if (ElementCountVal)
1245 *ElementCountVal = ElementCount;
1253 if (!ElementCount.isConstant())
1256 Idx = ElementCount.getAsInteger()->getLimitedValue();
1264 return {setPendingArrayDestruction(State, SF, Idx), Idx};
1287 llvm_unreachable(
"Unexpected dtor kind.");
1291 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1302 if (Opts.MayInlineCXXAllocator)
1310 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1327 const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
1342 std::tie(state, Idx) = prepareStateForArrayDestruction(
1343 state, Region, varType, SF, &ElementCount);
1345 if (ElementCount.isConstant()) {
1346 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1347 assert(ArrayLength &&
1348 "An automatic dtor for a 0 length array shouldn't be triggered!");
1353 "ExprEngine",
"Skipping automatic 0 length array destruction, "
1354 "which shouldn't be in the CFG.");
1357 Engine.makeNode(PP, Pred->
getState(), Pred,
true);
1369 "Prepare for object destruction");
1372 Pred = Engine.makeNode(PP, state, Pred);
1378 false, Pred, Dst, CallOpts);
1389 SVal ArgVal = State->getSVal(Arg, SF);
1393 if (State->isNull(ArgVal).isConstrainedTrue()) {
1403 auto getDtorDecl = [](
const QualType &DTy) {
1415 while (
const auto *AT =
getContext().getAsArrayType(DTy))
1416 DTy = AT->getElementType();
1420 std::tie(State, Idx) =
1421 prepareStateForArrayDestruction(State, ArgR, DTy, SF, &ElementCount);
1425 if (ElementCount.isConstant() &&
1426 ElementCount.getAsInteger()->getLimitedValue() == 0) {
1429 "ExprEngine",
"Skipping 0 length array delete destruction");
1436 ArgR = State->getLValue(DTy, svalBuilder.makeArrayIndex(Idx), ArgVal)
1442 "Prepare for object destruction");
1445 Pred = Engine.makeNode(PP, State, Pred);
1469 true, Pred, Dst, CallOpts);
1482 Loc ThisLoc = State->getSVal(ThisStorageLoc).
castAs<
Loc>();
1483 SVal FieldVal = State->getLValue(
Member, ThisLoc);
1488 std::tie(State, Idx) = prepareStateForArrayDestruction(
1489 State, FieldVal.getAsRegion(), T, SF, &ElementCount);
1491 if (ElementCount.isConstant()) {
1492 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1493 assert(ArrayLength &&
1494 "A member dtor for a 0 length array shouldn't be triggered!");
1499 "ExprEngine",
"Skipping member 0 length array destruction, which "
1500 "shouldn't be in the CFG.");
1503 Engine.makeNode(PP, Pred->
getState(), Pred,
true);
1514 "Prepare for object destruction");
1517 Pred = Engine.makeNode(PP, State, Pred);
1523 false, Pred, Dst, CallOpts);
1538 State = finishObjectConstruction(State, BTE, SF);
1539 MR =
V->getAsRegion();
1544 if (isDestructorElided(State, BTE, SF)) {
1545 State = cleanupElidedDestructor(State, BTE, SF);
1548 Dst.
insert(Engine.makeNode(PP, State, Pred));
1552 ExplodedNode *CleanPred = Engine.makePostStmtNode(BTE, State, Pred);
1553 if (!CleanPred || CleanPred->
isSink()) {
1583 T = AT->getElementType();
1594 false, CleanPred, Dst, CallOpts);
1606 if (
const CFGBlock *DstBlock = Obj ? DstT : DstF) {
1608 Dst.
insert(Engine.makeNode(BE, State, Pred));
1627 const StackFrame *SF = Node->getStackFrame();
1633 State = addObjectUnderConstruction(State, BTE, SF,
UnknownVal());
1635 Builder.generateNode(BTE, Node, State);
1643 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
1648 : Symbols(Symbols) {}
1652 bool VisitSymbol(
SymbolRef Sym)
override {
1653 Symbols.insert(Sym);
1658 CollectReachableSymbolsCallback CallBack(Symbols);
1660 State->scanReachableSymbols(
V, CallBack);
1663 State, CallBack.getSymbols(),
Call, K,
nullptr);
1677 case Stmt::CXXDependentScopeMemberExprClass:
1678 case Stmt::CXXReflectExprClass:
1679 case Stmt::CXXTryStmtClass:
1680 case Stmt::CXXTypeidExprClass:
1681 case Stmt::CXXUuidofExprClass:
1682 case Stmt::CXXFoldExprClass:
1683 case Stmt::MSPropertyRefExprClass:
1684 case Stmt::MSPropertySubscriptExprClass:
1685 case Stmt::CXXUnresolvedConstructExprClass:
1686 case Stmt::DependentScopeDeclRefExprClass:
1687 case Stmt::ArrayTypeTraitExprClass:
1688 case Stmt::ExpressionTraitExprClass:
1689 case Stmt::UnresolvedLookupExprClass:
1690 case Stmt::UnresolvedMemberExprClass:
1691 case Stmt::RecoveryExprClass:
1692 case Stmt::CXXNoexceptExprClass:
1693 case Stmt::PackExpansionExprClass:
1694 case Stmt::PackIndexingExprClass:
1695 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1696 case Stmt::FunctionParmPackExprClass:
1697 case Stmt::CoroutineBodyStmtClass:
1698 case Stmt::CoawaitExprClass:
1699 case Stmt::DependentCoawaitExprClass:
1700 case Stmt::CoreturnStmtClass:
1701 case Stmt::CoyieldExprClass:
1702 case Stmt::SEHTryStmtClass:
1703 case Stmt::SEHExceptStmtClass:
1704 case Stmt::SEHLeaveStmtClass:
1705 case Stmt::SEHFinallyStmtClass:
1706 case Stmt::OMPCanonicalLoopClass:
1707 case Stmt::OMPParallelDirectiveClass:
1708 case Stmt::OMPSimdDirectiveClass:
1709 case Stmt::OMPForDirectiveClass:
1710 case Stmt::OMPForSimdDirectiveClass:
1711 case Stmt::OMPSectionsDirectiveClass:
1712 case Stmt::OMPSectionDirectiveClass:
1713 case Stmt::OMPScopeDirectiveClass:
1714 case Stmt::OMPSingleDirectiveClass:
1715 case Stmt::OMPMasterDirectiveClass:
1716 case Stmt::OMPCriticalDirectiveClass:
1717 case Stmt::OMPParallelForDirectiveClass:
1718 case Stmt::OMPParallelForSimdDirectiveClass:
1719 case Stmt::OMPParallelSectionsDirectiveClass:
1720 case Stmt::OMPParallelMasterDirectiveClass:
1721 case Stmt::OMPParallelMaskedDirectiveClass:
1722 case Stmt::OMPTaskDirectiveClass:
1723 case Stmt::OMPTaskyieldDirectiveClass:
1724 case Stmt::OMPBarrierDirectiveClass:
1725 case Stmt::OMPTaskwaitDirectiveClass:
1726 case Stmt::OMPErrorDirectiveClass:
1727 case Stmt::OMPTaskgroupDirectiveClass:
1728 case Stmt::OMPFlushDirectiveClass:
1729 case Stmt::OMPDepobjDirectiveClass:
1730 case Stmt::OMPScanDirectiveClass:
1731 case Stmt::OMPOrderedDirectiveClass:
1732 case Stmt::OMPAtomicDirectiveClass:
1733 case Stmt::OMPAssumeDirectiveClass:
1734 case Stmt::OMPTargetDirectiveClass:
1735 case Stmt::OMPTargetDataDirectiveClass:
1736 case Stmt::OMPTargetEnterDataDirectiveClass:
1737 case Stmt::OMPTargetExitDataDirectiveClass:
1738 case Stmt::OMPTargetParallelDirectiveClass:
1739 case Stmt::OMPTargetParallelForDirectiveClass:
1740 case Stmt::OMPTargetUpdateDirectiveClass:
1741 case Stmt::OMPTeamsDirectiveClass:
1742 case Stmt::OMPCancellationPointDirectiveClass:
1743 case Stmt::OMPCancelDirectiveClass:
1744 case Stmt::OMPTaskLoopDirectiveClass:
1745 case Stmt::OMPTaskLoopSimdDirectiveClass:
1746 case Stmt::OMPMasterTaskLoopDirectiveClass:
1747 case Stmt::OMPMaskedTaskLoopDirectiveClass:
1748 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
1749 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
1750 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
1751 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
1752 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1753 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
1754 case Stmt::OMPDistributeDirectiveClass:
1755 case Stmt::OMPDistributeParallelForDirectiveClass:
1756 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1757 case Stmt::OMPDistributeSimdDirectiveClass:
1758 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1759 case Stmt::OMPTargetSimdDirectiveClass:
1760 case Stmt::OMPTeamsDistributeDirectiveClass:
1761 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1762 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1763 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1764 case Stmt::OMPTargetTeamsDirectiveClass:
1765 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1766 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1767 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1768 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1769 case Stmt::OMPReverseDirectiveClass:
1770 case Stmt::OMPStripeDirectiveClass:
1771 case Stmt::OMPTileDirectiveClass:
1772 case Stmt::OMPInterchangeDirectiveClass:
1773 case Stmt::OMPSplitDirectiveClass:
1774 case Stmt::OMPFuseDirectiveClass:
1775 case Stmt::OMPInteropDirectiveClass:
1776 case Stmt::OMPDispatchDirectiveClass:
1777 case Stmt::OMPMaskedDirectiveClass:
1778 case Stmt::OMPGenericLoopDirectiveClass:
1779 case Stmt::OMPTeamsGenericLoopDirectiveClass:
1780 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
1781 case Stmt::OMPParallelGenericLoopDirectiveClass:
1782 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
1783 case Stmt::CapturedStmtClass:
1784 case Stmt::SYCLKernelCallStmtClass:
1785 case Stmt::UnresolvedSYCLKernelCallStmtClass:
1786 case Stmt::OpenACCComputeConstructClass:
1787 case Stmt::OpenACCLoopConstructClass:
1788 case Stmt::OpenACCCombinedConstructClass:
1789 case Stmt::OpenACCDataConstructClass:
1790 case Stmt::OpenACCEnterDataConstructClass:
1791 case Stmt::OpenACCExitDataConstructClass:
1792 case Stmt::OpenACCHostDataConstructClass:
1793 case Stmt::OpenACCWaitConstructClass:
1794 case Stmt::OpenACCCacheConstructClass:
1795 case Stmt::OpenACCInitConstructClass:
1796 case Stmt::OpenACCShutdownConstructClass:
1797 case Stmt::OpenACCSetConstructClass:
1798 case Stmt::OpenACCUpdateConstructClass:
1799 case Stmt::OpenACCAtomicConstructClass:
1800 case Stmt::OMPUnrollDirectiveClass:
1801 case Stmt::OMPMetaDirectiveClass:
1802 case Stmt::HLSLOutArgExprClass: {
1808 case Stmt::ParenExprClass:
1809 llvm_unreachable(
"ParenExprs already handled.");
1810 case Stmt::GenericSelectionExprClass:
1811 llvm_unreachable(
"GenericSelectionExprs already handled.");
1814 case Stmt::BreakStmtClass:
1815 case Stmt::CaseStmtClass:
1816 case Stmt::CompoundStmtClass:
1817 case Stmt::ContinueStmtClass:
1818 case Stmt::CXXForRangeStmtClass:
1819 case Stmt::DefaultStmtClass:
1820 case Stmt::DoStmtClass:
1821 case Stmt::ForStmtClass:
1822 case Stmt::GotoStmtClass:
1823 case Stmt::IfStmtClass:
1824 case Stmt::IndirectGotoStmtClass:
1825 case Stmt::LabelStmtClass:
1827 case Stmt::NullStmtClass:
1828 case Stmt::SwitchStmtClass:
1829 case Stmt::WhileStmtClass:
1830 case Stmt::DeferStmtClass:
1831 case Expr::MSDependentExistsStmtClass:
1832 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
1833 case Stmt::ImplicitValueInitExprClass:
1837 llvm_unreachable(
"Should be pruned from CFG");
1839 case Stmt::ObjCSubscriptRefExprClass:
1840 case Stmt::ObjCPropertyRefExprClass:
1841 llvm_unreachable(
"These are handled by PseudoObjectExpr");
1843 case Stmt::GNUNullExprClass: {
1846 state = state->BindExpr(
1848 svalBuilder.makeIntValWithWidth(
getContext().VoidPtrTy, 0));
1853 case Stmt::ObjCAtSynchronizedStmtClass:
1859 case Expr::ConstantExprClass:
1860 case Stmt::ExprWithCleanupsClass:
1864 case Stmt::CXXBindTemporaryExprClass: {
1875 case Stmt::ArrayInitLoopExprClass:
1881 case Stmt::DesignatedInitExprClass:
1882 case Stmt::DesignatedInitUpdateExprClass:
1883 case Stmt::ArrayInitIndexExprClass:
1884 case Stmt::ExtVectorElementExprClass:
1885 case Stmt::MatrixElementExprClass:
1886 case Stmt::ImaginaryLiteralClass:
1887 case Stmt::ObjCAtCatchStmtClass:
1888 case Stmt::ObjCAtFinallyStmtClass:
1889 case Stmt::ObjCAtTryStmtClass:
1890 case Stmt::ObjCAutoreleasePoolStmtClass:
1891 case Stmt::ObjCEncodeExprClass:
1892 case Stmt::ObjCIsaExprClass:
1893 case Stmt::ObjCProtocolExprClass:
1894 case Stmt::ObjCSelectorExprClass:
1895 case Stmt::ParenListExprClass:
1896 case Stmt::ShuffleVectorExprClass:
1897 case Stmt::ConvertVectorExprClass:
1898 case Stmt::VAArgExprClass:
1899 case Stmt::CUDAKernelCallExprClass:
1900 case Stmt::OpaqueValueExprClass:
1901 case Stmt::AsTypeExprClass:
1902 case Stmt::ConceptSpecializationExprClass:
1903 case Stmt::CXXRewrittenBinaryOperatorClass:
1904 case Stmt::RequiresExprClass:
1905 case Stmt::EmbedExprClass:
1910 case Stmt::PredefinedExprClass:
1911 case Stmt::AddrLabelExprClass:
1912 case Stmt::IntegerLiteralClass:
1913 case Stmt::FixedPointLiteralClass:
1914 case Stmt::CharacterLiteralClass:
1915 case Stmt::CXXScalarValueInitExprClass:
1916 case Stmt::CXXBoolLiteralExprClass:
1917 case Stmt::ObjCBoolLiteralExprClass:
1918 case Stmt::ObjCAvailabilityCheckExprClass:
1919 case Stmt::FloatingLiteralClass:
1920 case Stmt::NoInitExprClass:
1921 case Stmt::SizeOfPackExprClass:
1922 case Stmt::StringLiteralClass:
1923 case Stmt::SourceLocExprClass:
1924 case Stmt::ObjCStringLiteralClass:
1925 case Stmt::CXXPseudoDestructorExprClass:
1926 case Stmt::SubstNonTypeTemplateParmExprClass:
1927 case Stmt::CXXNullPtrLiteralExprClass:
1928 case Stmt::ArraySectionExprClass:
1929 case Stmt::OMPArrayShapingExprClass:
1930 case Stmt::OMPIteratorExprClass:
1931 case Stmt::SYCLUniqueStableNameExprClass:
1932 case Stmt::OpenACCAsteriskSizeExprClass:
1933 case Stmt::TypeTraitExprClass: {
1942 case Stmt::AttributedStmtClass: {
1949 case Stmt::CXXDefaultArgExprClass:
1950 case Stmt::CXXDefaultInitExprClass: {
1959 if (
const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
1960 ArgE = DefE->getExpr();
1961 else if (
const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
1962 ArgE = DefE->getExpr();
1964 llvm_unreachable(
"unknown constant wrapper kind");
1966 bool IsTemporary =
false;
1967 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
1968 ArgE = MTE->getSubExpr();
1972 std::optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
1977 for (
const auto I : PreVisit) {
1979 State = State->BindExpr(
cast<Expr>(S), SF, *ConstantVal);
1981 State = createTemporaryRegionIfNeeded(State, SF,
cast<Expr>(S),
1992 case Stmt::CXXStdInitializerListExprClass:
1993 case Expr::ObjCArrayLiteralClass:
1994 case Expr::ObjCDictionaryLiteralClass:
1995 case Expr::ObjCBoxedExprClass: {
2005 QualType resultType = Ex->getType();
2007 for (
const auto N : preVisit) {
2009 SVal result = svalBuilder.conjureSymbolVal(
2019 for (
auto Child : Ex->children()) {
2021 const auto *ChildExpr = dyn_cast<Expr>(Child);
2022 SVal Val = ChildExpr ? State->getSVal(ChildExpr, SF) :
UnknownVal();
2034 case Stmt::ArraySubscriptExprClass:
2040 case Stmt::MatrixSingleSubscriptExprClass:
2042 "Support for MatrixSingleSubscriptExprClass is not implemented.");
2045 case Stmt::MatrixSubscriptExprClass:
2046 llvm_unreachable(
"Support for MatrixSubscriptExpr is not implemented.");
2049 case Stmt::GCCAsmStmtClass: {
2061 case Stmt::MSAsmStmtClass:
2067 case Stmt::BlockExprClass:
2073 case Stmt::LambdaExprClass:
2074 if (AMgr.options.ShouldInlineLambdas) {
2084 case Stmt::BinaryOperatorClass: {
2086 if (B->isLogicalOp()) {
2092 else if (B->getOpcode() == BO_Comma) {
2104 if (AMgr.options.ShouldEagerlyAssume &&
2105 (B->isRelationalOp() || B->isEqualityOp())) {
2117 case Stmt::CXXOperatorCallExprClass: {
2122 const Decl *Callee = OCE->getCalleeDecl();
2123 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
2124 if (MD->isImplicitObjectMemberFunction()) {
2128 createTemporaryRegionIfNeeded(State, SF, OCE->getArg(0));
2129 if (NewState != State) {
2141 case Stmt::CallExprClass:
2142 case Stmt::CXXMemberCallExprClass:
2143 case Stmt::UserDefinedLiteralClass:
2149 case Stmt::CXXCatchStmtClass:
2155 case Stmt::CXXTemporaryObjectExprClass:
2156 case Stmt::CXXConstructExprClass:
2162 case Stmt::CXXInheritedCtorInitExprClass:
2169 case Stmt::CXXNewExprClass: {
2176 for (
const auto i : PreVisit)
2184 case Stmt::CXXDeleteExprClass: {
2192 for (
const auto i : PostVisit)
2201 case Stmt::ChooseExprClass: {
2209 case Stmt::CompoundAssignOperatorClass:
2215 case Stmt::CompoundLiteralExprClass:
2221 case Stmt::BinaryConditionalOperatorClass:
2222 case Stmt::ConditionalOperatorClass: {
2230 case Stmt::CXXThisExprClass:
2236 case Stmt::DeclRefExprClass: {
2244 case Stmt::DeclStmtClass:
2250 case Stmt::ImplicitCastExprClass:
2251 case Stmt::CStyleCastExprClass:
2252 case Stmt::CXXStaticCastExprClass:
2253 case Stmt::CXXDynamicCastExprClass:
2254 case Stmt::CXXReinterpretCastExprClass:
2255 case Stmt::CXXConstCastExprClass:
2256 case Stmt::CXXFunctionalCastExprClass:
2257 case Stmt::BuiltinBitCastExprClass:
2258 case Stmt::ObjCBridgedCastExprClass:
2259 case Stmt::CXXAddrspaceCastExprClass: {
2271 case Expr::MaterializeTemporaryExprClass: {
2277 for (
const auto i : dstPrevisit)
2284 case Stmt::InitListExprClass: {
2292 case Expr::CXXParenListInitExprClass: {
2301 case Stmt::MemberExprClass:
2307 case Stmt::AtomicExprClass:
2313 case Stmt::ObjCIvarRefExprClass:
2319 case Stmt::ObjCForCollectionStmtClass:
2325 case Stmt::ObjCMessageExprClass:
2331 case Stmt::ObjCAtThrowStmtClass:
2332 case Stmt::CXXThrowExprClass:
2338 case Stmt::ReturnStmtClass:
2344 case Stmt::OffsetOfExprClass: {
2350 for (
const auto Node : PreVisit)
2358 case Stmt::UnaryExprOrTypeTraitExprClass:
2365 case Stmt::StmtExprClass: {
2368 if (SE->getSubStmt()->body_empty()) {
2371 &&
"Empty statement expression must have void type.");
2375 if (
const auto *LastExpr =
2376 dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
2386 case Stmt::UnaryOperatorClass: {
2389 if (AMgr.options.ShouldEagerlyAssume && (
U->getOpcode() == UO_LNot)) {
2400 case Stmt::PseudoObjectExprClass: {
2404 if (
const Expr *
Result = PE->getResultExpr()) {
2418 case Expr::ObjCIndirectCopyRestoreExprClass: {
2425 const Expr *E = OIE->getSubExpr();
2438 assert(CalleeSF && CallerSF);
2445 BeforeProcessingCall = N;
2460 if (SP->getStmt() == CE)
2465 if (!BeforeProcessingCall)
2501 NumTimesRetriedWithoutInlining++;
2515 if(AMgr.options.ShouldUnrollLoops) {
2516 unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
2520 Pred, maxBlockVisitOnPath);
2521 if (NewState != Pred->
getState()) {
2522 ExplodedNode *UpdatedNode = Builder.generateNode(BE, NewState, Pred);
2536 if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
2537 AMgr.options.ShouldWidenLoops) {
2539 if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
2553 Builder.generateNode(BE, WidenedState, Pred);
2558 if (BlockCount >= AMgr.options.maxBlockVisitOnPath) {
2562 Builder.generateSink(TaggedLoc, Pred->
getState(), Pred);
2575 Engine.FunctionSummaries->markShouldNotInline(SF->
getDecl());
2581 if ((!AMgr.options.NoRetryExhausted && replayWithoutInlining(Pred, SF)))
2583 NumMaxBlockCountReachedInInlined++;
2585 NumMaxBlockCountReached++;
2588 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
2595 llvm::PrettyStackTraceFormat CrashInfo(
2596 "Processing block entrance B%d -> B%d",
2614 const auto *Ex = dyn_cast<Expr>(
Condition);
2619 bool bitsInit =
false;
2621 while (
const auto *CE = dyn_cast<CastExpr>(Ex)) {
2624 if (!T->isIntegralOrEnumerationType())
2628 if (!bitsInit || newBits < bits) {
2633 Ex = CE->getSubExpr();
2639 if (!bitsInit || !T->isIntegralOrEnumerationType() ||
2643 return state->getSVal(Ex, SF);
2649 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2650 if (!BO || !BO->isLogicalOp()) {
2653 Condition = BO->getRHS()->IgnoreParens();
2675 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2678 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2679 if (!BO || !BO->isLogicalOp())
2683 "Other kinds of branches are handled separately!");
2694 std::optional<CFGStmt> CS = Elem.getAs<
CFGStmt>();
2697 const Stmt *LastStmt = CS->getStmt();
2701 llvm_unreachable(
"could not resolve condition");
2705 std::pair<const ObjCForCollectionStmt *, const StackFrame *>;
2711 bool HasMoreIteraton) {
2712 assert(!State->contains<ObjCForHasMoreIterations>({O, SF}));
2713 return State->set<ObjCForHasMoreIterations>({O, SF}, HasMoreIteraton);
2719 assert(State->contains<ObjCForHasMoreIterations>({O, SF}));
2720 return State->remove<ObjCForHasMoreIterations>({O, SF});
2726 assert(State->contains<ObjCForHasMoreIterations>({O, SF}));
2727 return *State->get<ObjCForHasMoreIterations>({O, SF});
2733static std::optional<std::pair<ProgramStateRef, ProgramStateRef>>
2736 if (
const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(ConditionStmt)) {
2737 bool HasMoreIteraton =
2744 if (HasMoreIteraton)
2745 return std::pair<ProgramStateRef, ProgramStateRef>{State,
nullptr};
2747 return std::pair<ProgramStateRef, ProgramStateRef>{
nullptr, State};
2750 const auto *ConditionExpr = dyn_cast<Expr>(ConditionStmt);
2751 assert(ConditionExpr &&
"The condition must be an Expr from here!");
2755 if (
X.isUnknownOrUndef()) {
2757 if (
const auto *Ex = dyn_cast<Expr>(ConditionExpr)) {
2758 if (Ex->getType()->isIntegralOrEnumerationType()) {
2765 N->
getState()->getStateManager().getContext());
2775 if (
X.isUnknownOrUndef())
2776 return std::nullopt;
2781 return State->assume(
V);
2787 std::optional<unsigned> IterationsCompletedInLoop) {
2789 "CXXBindTemporaryExprs are handled by processBindTemporary.");
2805 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2811 "Error evaluating branch");
2817 if (CheckersOutSet.
empty())
2825 std::tie(StTrue, StFalse) = *KnownCondValueAssumption;
2827 if (StTrue && StFalse)
2838 (StTrue && StFalse) ||
2857 bool CompletedTwoIterations = IterationsCompletedInLoop.value_or(0) >= 2;
2858 bool SkipTrueBranch = BothFeasible && CompletedTwoIterations;
2864 if (!SkipTrueBranch || AMgr.options.ShouldWidenLoops) {
2867 Dst.
insert(Engine.makeNode(BE, StTrue, PredN));
2869 }
else if (!AMgr.options.InlineFunctionsWithAmbiguousLoops) {
2886 Engine.FunctionSummaries->markShouldNotInline(SF->
getDecl());
2904 bool BeforeFirstIteration = IterationsCompletedInLoop == std::optional{0};
2905 bool SkipFalseBranch = BothFeasible && BeforeFirstIteration &&
2906 AMgr.options.ShouldAssumeAtLeastOneIteration;
2907 if (!SkipFalseBranch && DstF) {
2909 Dst.
insert(Engine.makeNode(BE, StFalse, PredN));
2918 llvm::ImmutableSet<const VarDecl *>)
2927 bool InitHasRun = State->contains<InitializedGlobalsSet>(VD);
2929 State = State->add<InitializedGlobalsSet>(VD);
2931 if (
const CFGBlock *DstBlock = InitHasRun ? DstT : DstF) {
2965 Dst.
insert(Engine.makeNode(BE, State, Pred));
2983 State = finishArgumentConstruction(
2998 while (SF != ToSF) {
2999 assert(SF &&
"ToSF must be a parent of FromSF!");
3000 for (
auto I : State->get<ObjectsUnderConstruction>())
3001 if (I.first.getStackFrame() == SF) {
3005 assert(I.first.getItem().getKind() ==
3007 I.first.getItem().getKind() ==
3009 State = State->remove<ObjectsUnderConstruction>(I.first);
3017 Pred = Engine.makeNode(Pred->
getLocation(), State, Pred);
3034 for (
const auto I : AfterRemovedDead)
3040 Engine.enqueueEndOfFunction(Dst, RS);
3054 assert(SwitchBlock->
succ_size() &&
"Switch must have at least one successor");
3060 llvm::iterator_range<CFGBlock::const_succ_reverse_iterator> CaseBlocks(
3067 Condition->IgnoreParens(), CheckersOutSet, Pred, *
this);
3077 std::optional<NonLoc> CondNL = CondV.
getAs<
NonLoc>();
3079 for (
const CFGBlock *CaseBlock : CaseBlocks) {
3088 assert(V1.getBitWidth() ==
3094 V2 = E->EvaluateKnownConstInt(ACtx);
3101 std::tie(StateMatching, State) =
3102 State->assumeInclusiveRange(*CondNL, V1, V2);
3106 StateMatching = State;
3109 if (StateMatching) {
3110 BlockEdge BE(SwitchBlock, CaseBlock, SF);
3111 Dst.
insert(Engine.makeNode(BE, StateMatching, Node));
3133 if (
Condition->IgnoreParenImpCasts()->getType()->isEnumeralType()) {
3134 if (
Switch->isAllEnumCasesCovered())
3138 BlockEdge BE(SwitchBlock, DefaultBlock, SF);
3139 Dst.
insert(Engine.makeNode(BE, State, Node));
3153 auto resolveAsLambdaCapturedVar =
3154 [&](
const ValueDecl *VD) -> std::optional<std::pair<SVal, QualType>> {
3155 const auto *MD = dyn_cast<CXXMethodDecl>(SF->
getDecl());
3156 const auto *DeclRefEx = dyn_cast<DeclRefExpr>(Ex);
3157 if (AMgr.options.ShouldInlineLambdas && DeclRefEx &&
3158 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
3159 MD->getParent()->isLambda()) {
3162 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
3168 if (
const FieldDecl *FD = LambdaCaptureFields[VD]) {
3169 Loc CXXThis = svalBuilder.getCXXThis(MD, SF);
3171 return std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
3175 return std::nullopt;
3178 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
3181 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
3182 std::optional<std::pair<SVal, QualType>> VInfo =
3183 resolveAsLambdaCapturedVar(VD);
3186 VInfo = std::make_pair(state->getLValue(VD, SF), VD->getType());
3188 SVal V = VInfo->first;
3189 bool IsReference = VInfo->second->isReferenceType();
3195 V = state->getSVal(R);
3204 if (
const auto *ED = dyn_cast<EnumConstantDecl>(D)) {
3206 SVal V = svalBuilder.makeIntVal(ED->getInitVal());
3207 Dst.
insert(Engine.makeNodeWithBinding(Pred, Ex,
V));
3210 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
3211 SVal V = svalBuilder.getFunctionPointer(FD);
3222 if (
const auto *BD = dyn_cast<BindingDecl>(D)) {
3224 if (std::optional<std::pair<SVal, QualType>> VInfo =
3225 resolveAsLambdaCapturedVar(BD)) {
3226 auto [
V, T] = VInfo.value();
3228 if (T->isReferenceType()) {
3230 V = state->getSVal(R);
3235 Dst.
insert(Engine.makeNodeWithBinding(Pred, Ex,
V,
3242 SVal Base = state->getLValue(DD, SF);
3243 if (DD->getType()->isReferenceType()) {
3245 Base = state->getSVal(R);
3253 if (
const auto *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
3255 V = state->getLValue(Field,
Base);
3258 else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BD->getBinding())) {
3259 SVal Idx = state->getSVal(ASE->getIdx(), SF);
3264 assert(Idx.
isConstant() &&
"BindingDecl array index is not a constant!");
3266 V = state->getLValue(BD->getType(), Idx,
Base);
3269 else if (
const auto *HV = BD->getHoldingVar()) {
3270 V = state->getLValue(HV, SF);
3272 if (HV->getType()->isReferenceType()) {
3274 V = state->getSVal(R);
3279 llvm_unreachable(
"An unknown case of structured binding encountered!");
3283 if (BD->getType()->isReferenceType() && !BD->getHoldingVar()) {
3285 V = state->getSVal(R);
3295 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
3302 llvm_unreachable(
"Support for this Decl not implemented.");
3313 NodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
3317 for (
auto *Node : CheckerPreStmt) {
3323 const StackFrame *SF = Node->getStackFrame();
3362 if (
const auto *ME = dyn_cast<MemberExpr>(Arr)) {
3363 Expr *MEBase = ME->getBase();
3366 if (
auto CXXSCE = dyn_cast<CXXStaticCastExpr>(MEBase)) {
3367 MEBase = CXXSCE->getSubExpr();
3388 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arr))
3393 Base = state->getSVal(R);
3421 (A->
getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
3423 for (
auto *Node : CheckerPreStmt) {
3424 const StackFrame *SF = Node->getStackFrame();
3427 if (IsGLValueLike) {
3433 if (T->isVoidType())
3436 SVal V = state->getLValue(T, state->getSVal(Idx, SF),
3437 state->getSVal(
Base, SF));
3440 }
else if (IsVectorType) {
3442 EvalSet.
insert(Engine.makePostStmtNode(A, state, Node));
3444 llvm_unreachable(
"Array subscript should be an lValue when not \
3445a vector and not a forbidden lvalue type");
3465 for (
const auto I : CheckedSet)
3468 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
3471 for (
const auto I : CheckedSet) {
3477 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member)) {
3478 if (MD->isImplicitObjectMemberFunction())
3479 state = createTemporaryRegionIfNeeded(state, SF, BaseExpr);
3481 SVal MDVal = svalBuilder.getFunctionPointer(MD);
3482 state = state->BindExpr(M, SF, MDVal);
3490 state = createTemporaryRegionIfNeeded(state, SF, BaseExpr,
3497 if (
const auto *SR =
3498 dyn_cast_or_null<SymbolicRegion>(baseExprVal.
getAsRegion())) {
3499 QualType T = SR->getPointeeStaticType();
3505 SVal L = state->getLValue(field, baseExprVal);
3515 dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
3516 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
3517 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
3521 if (field->getType()->isReferenceType()) {
3523 L = state->getSVal(R);
3528 Bldr.
generateNode(M, I, state->BindExpr(M, SF, L),
nullptr,
3550 NodeBuilder Bldr(AfterPreSet, AfterInvalidateSet, *currBldrCtx);
3552 for (
const auto I : AfterPreSet) {
3557 for (
unsigned SI = 0, Count = AE->
getNumSubExprs(); SI != Count; SI++) {
3559 SVal SubExprVal = State->getSVal(SubExpr, SF);
3560 ValuesToInvalidate.push_back(SubExprVal);
3569 State = State->BindExpr(AE, SF, ResultVal);
3588 for (
const std::pair<SVal, SVal> &LocAndVal : LocAndVals) {
3590 const MemRegion *MR = LocAndVal.first.getAsRegion();
3593 Escaped.push_back(LocAndVal.second);
3598 if (
const auto *VR = dyn_cast<VarRegion>(MR->
getBaseRegion()))
3600 VR->getStackFrame()->inTopFrame())
3601 if (
const auto *RD = VR->getValueType()->getAsCXXRecordDecl())
3602 if (!RD->hasTrivialDestructor()) {
3603 Escaped.push_back(LocAndVal.second);
3612 SVal StoredVal = State->getSVal(MR);
3613 if (StoredVal != LocAndVal.second)
3616 Escaped.push_back(LocAndVal.second);
3619 if (Escaped.empty())
3628 std::pair<SVal, SVal> LocAndVal(
Loc, Val);
3639 if (!Invalidated || Invalidated->empty())
3652 for (
const auto I : ExplicitRegions) {
3654 SymbolsDirectlyInvalidated.insert(R->getSymbol());
3658 for (
const auto &sym : *Invalidated) {
3659 if (SymbolsDirectlyInvalidated.count(sym))
3661 SymbolsIndirectlyInvalidated.insert(sym);
3664 if (!SymbolsDirectlyInvalidated.empty())
3669 if (!SymbolsIndirectlyInvalidated.empty())
3683 assert(!
isa<NonLoc>(Location) &&
"evalBind location should not be NonLoc!");
3694 StoreE, AtDeclInit, *
this, *PP);
3702 if (
auto AsLoc = Location.getAs<
Loc>()) {
3706 State = State->bindLoc(*AsLoc, Val, SF, !AtDeclInit);
3709 PostStore PS(StoreE, SF, Location.getAsRegion(),
nullptr);
3723 const Expr *LocationE,
3729 const Expr *StoreE = AssignE ? AssignE : LocationE;
3733 evalLocation(Tmp, AssignE, LocationE, Pred, state, location,
false);
3741 for (
const auto I : Tmp)
3742 evalBind(Dst, StoreE, I, location, Val,
false);
3747 const Expr *BoundEx,
3753 assert(!
isa<NonLoc>(location) &&
"location cannot be a NonLoc.");
3758 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location,
true);
3767 for (
const auto I : Tmp) {
3768 state = I->getState();
3774 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
3778 state->BindExpr(BoundEx, I->getStackFrame(),
V), tag,
3785 const Stmt *BoundEx,
3797 BldrTop.takeNodes(Pred);
3810 Bldr.generateNode(NodeEx, Pred, state, &tag);
3814 NodeEx, BoundEx, *
this);
3815 BldrTop.addNodes(Tmp);
3818std::pair<const ProgramPointTag *, const ProgramPointTag *>
3821 FalseTag(TagProviderName,
"Eagerly Assume False");
3823 return std::make_pair(&TrueTag, &FalseTag);
3847 State = State->set<LastEagerlyAssumeExprIfSuccessful>(
nullptr);
3850 if (SEV && SEV->isExpression()) {
3853 auto [StateTrue, StateFalse] = State->assume(*SEV);
3855 if (StateTrue && StateFalse) {
3856 StateTrue = StateTrue->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3857 StateFalse = StateFalse->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3863 StateTrue = StateTrue->BindExpr(Ex, Pred->
getStackFrame(), Val);
3870 StateFalse = StateFalse->BindExpr(Ex, Pred->
getStackFrame(), Val);
3878 const Expr *Ex)
const {
3879 return Ex && State->get<LastEagerlyAssumeExprIfSuccessful>() == Ex;
3898 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3909 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3940 for (
const auto &
Report : Class.getReports()) {
3941 const auto *PR = dyn_cast<PathSensitiveBugReport>(
Report.get());
3959 llvm::function_ref<
void(
const ExplodedNode *)> PreCallback,
3960 llvm::function_ref<
void(
const ExplodedNode *)> PostCallback,
3982 llvm::raw_string_ostream Out(Buf);
3984 const bool IsDot =
true;
3985 const unsigned int Space = 1;
3988 Out <<
"{ \"state_id\": " << State->getID()
3991 Indent(Out, Space, IsDot) <<
"\"program_points\": [\\l";
3997 Indent(Out, Space + 1, IsDot) <<
"{ ";
3999 Out <<
", \"tag\": ";
4001 Out <<
'\"' << Tag->getDebugTag() <<
'\"';
4004 Out <<
", \"node_id\": " << OtherNode->
getID() <<
4005 ", \"is_sink\": " << OtherNode->
isSink() <<
4013 Indent(Out, Space, IsDot) <<
"],\\l";
4026 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
4030 std::string Filename =
DumpGraph(Nodes);
4031 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
4036 std::vector<const ExplodedNode *> Src;
4039 for (
const auto &
Class : BR.equivalenceClasses()) {
4041 dyn_cast<PathSensitiveBugReport>(
Class.getReports()[0].get());
4044 const auto *N =
const_cast<ExplodedNode *
>(R->getErrorNode());
4051 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
4052 return llvm::WriteGraph(&G,
"ExprEngine",
false,
4054 std::string(Filename));
4058 StringRef Filename) {
4059 std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
4062 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
4067 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
4068 return llvm::WriteGraph(TrimmedG.get(),
"TrimmedExprEngine",
4070 "Trimmed Exploded Graph",
4071 std::string(Filename));
4075 static int index = 0;
4079void ExprEngine::anchor() { }
4092 bool IsCompound = T->
isArrayType() || T->isRecordType() ||
4093 T->isAnyComplexType() || T->isVectorType();
4095 if (Args.size() > 1 || (E->
isPRValue() && IsCompound && !IsTransparent)) {
4097 for (
Expr *E : llvm::reverse(Args))
4101 S->BindExpr(E, SF, svalBuilder.makeCompoundVal(T, ArgList)));
4107 : S->getSVal(Args.front(), SF)));
Defines the clang::ASTContext interface.
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
static const MemRegion * getRegion(const CallEvent &Call, const MutexDescriptor &Descriptor, bool IsLock)
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define STAT_COUNTER(VARNAME, DESC)
Defines the clang::Expr interface and subclasses for C++ expressions.
static const Stmt * getRightmostLeaf(const Stmt *Condition)
static void printIndicesOfElementsToConstructJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const StackFrame *SF, unsigned int Space=0, bool IsDot=false)
static const Stmt * ResolveCondition(const Stmt *Condition, const CFGBlock *B)
std::pair< const ObjCForCollectionStmt *, const StackFrame * > ObjCForLctxPair
static SVal RecoverCastedSymbol(ProgramStateRef state, const Stmt *Condition, const StackFrame *SF, ASTContext &Ctx)
RecoverCastedSymbol - A helper function for ProcessBranch that is used to try to recover some path-se...
static void printStateTraitWithStackFrameJson(raw_ostream &Out, ProgramStateRef State, const StackFrame *SF, const char *NL, unsigned int Space, bool IsDot, const char *jsonPropertyName, Printer printer, Args &&...args)
A helper function to generalize program state trait printing.
static void printPendingInitLoopJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const StackFrame *SF, unsigned int Space=0, bool IsDot=false)
REGISTER_TRAIT_WITH_PROGRAMSTATE(ObjectsUnderConstruction, ObjectsUnderConstructionMap) typedef llvm REGISTER_TRAIT_WITH_PROGRAMSTATE(IndexOfElementToConstruct, IndexOfElementToConstructMap) typedef llvm typedef llvm::ImmutableMap< const StackFrame *, unsigned > PendingArrayDestructionMap
llvm::ImmutableMap< ConstructedObjectKey, SVal > ObjectsUnderConstructionMap
static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S, const ExplodedNode *Pred, const StackFrame *SF)
static void printObjectsUnderConstructionJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const StackFrame *SF, unsigned int Space=0, bool IsDot=false)
static std::optional< std::pair< ProgramStateRef, ProgramStateRef > > assumeCondition(const Stmt *ConditionStmt, ExplodedNode *N)
Split the state on whether there are any more iterations left for this loop.
static void printPendingArrayDestructionsJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const StackFrame *SF, unsigned int Space=0, bool IsDot=false)
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Result
Implement __builtin_bit_cast and related operations.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
This header contains the declarations of functions which are used to decide which loops should be com...
This header contains the declarations of functions which are used to widen loops which do not otherwi...
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
Declares a program state trait for type Type called Name, and introduce a type named NameTy.
static bool isRecordType(QualType T)
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
Defines the Objective-C statement AST node classes.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const clang::PrintingPolicy & getPrintingPolicy() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ParentMap & getParentMap()
ASTContext & getASTContext() const
Stores options for the analyzer from the command line.
AnalysisPurgeMode AnalysisPurgeOpt
Represents a loop initializing the elements of an array.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
static unsigned getNumSubExprs(AtomicOp Op)
Determine the number of arguments the specified atomic builtin should have.
const CFGBlock * getPreviousBlock() const
const CFGBlock * getBlock() const
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
const VarDecl * getVarDecl() const
const Stmt * getTriggerStmt() const
Represents C++ object destructor implicitly generated for base object in destructor.
const CXXBaseSpecifier * getBaseSpecifier() const
Represents a single basic block in a source-level CFG.
succ_reverse_iterator succ_rend()
succ_reverse_iterator succ_rbegin()
CFGTerminator getTerminator() const
Stmt * getTerminatorStmt()
unsigned getBlockID() const
unsigned succ_size() const
Represents C++ object destructor generated from a call to delete.
const CXXDeleteExpr * getDeleteExpr() const
Represents a top-level expression in a basic block.
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
Represents C++ object destructor implicitly generated by compiler on various occasions.
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
Represents C++ base or member initializer from constructor's initialization list.
const CXXCtorInitializer * getInitializer() const
Represents the point where a loop ends.
const Stmt * getLoopStmt() const
Represents C++ object destructor implicitly generated for member object in destructor.
const FieldDecl * getFieldDecl() const
Represents C++ allocator call.
const CXXNewExpr * getAllocatorExpr() const
const Stmt * getStmt() const
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
bool isStmtBranch() const
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
const Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a call to a C++ constructor.
Represents a C++ base or member initializer.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
bool isDelegatingInitializer() const
Determine whether this initializer is creating a delegating constructor.
Expr * getInit() const
Get the initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
int64_t getID(const ASTContext &Context) const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a delete expression for memory deallocation and destructor calls, e.g.
SourceLocation getBeginLoc() const
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ destructor within a class.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Represents a point when we begin processing an inlined call.
CaseStmt - Represent a case statement.
Represents a single point (AST node) in the program that requires attention during construction of an...
unsigned getIndex() const
If a single trigger statement triggers multiple constructors, they are usually being enumerated.
const CXXCtorInitializer * getCXXCtorInitializer() const
The construction site is not necessarily a statement.
@ TemporaryDestructorKind
const Stmt * getStmtOrNull() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
const Decl * getSingleDecl() const
Decl - This represents one declaration (or definition), e.g.
This is a meta program point, which should be skipped by all the diagnostic reasoning etc.
This represents one expression.
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...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Represents a member of a struct/union/class.
This represents a GCC inline-assembly statement extension.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
ArrayRef< Expr * > inits() const
Represents the declaration of a label.
Represents a point when we exit a loop.
This represents a Microsoft inline-assembly statement extension.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents Objective-C's collection statement.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
bool isConsumedExpr(Expr *E) const
Represents a parameter to a function.
Represents a program point just after an implicit call event.
Represents a program point after a store evaluation.
Represents a program point just before an implicit call event.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
const ProgramPointTag * getTag() const
bool isPurgeKind()
Is this a program point corresponding to purge/removal of dead symbols and bindings.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type.
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, const StackFrame *SF, const ProgramPointTag *tag)
void printJson(llvm::raw_ostream &Out, const char *NL="\n") const
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
@ PreStmtPurgeDeadSymbolsKind
@ PostStmtPurgeDeadSymbolsKind
const StackFrame * getStackFrame() const
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
std::string getAsString() const
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
std::string printToString(const SourceManager &SM) const
It represents a stack frame of the call stack.
unsigned getIndex() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
void printJson(raw_ostream &Out, const char *NL="\n", unsigned int Space=0, bool IsDot=false, std::function< void(const StackFrame *)> printMoreInfoPerStackFrame=[](const StackFrame *) {}) const
Prints out the call stack in json format.
const Expr * getCallSite() const
const Decl * getDecl() const
const StackFrame * getParent() const
It might return null.
const CFGBlock * getCallSiteBlock() const
const Stmt * getStmt() const
Stmt - This represents one statement.
void printJson(raw_ostream &Out, PrinterHelper *Helper, const PrintingPolicy &Policy, bool AddQuotes) const
Pretty-prints in JSON format.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const char * getStmtClassName() const
int64_t getID(const ASTContext &Context) const
SourceLocation getBeginLoc() const LLVM_READONLY
SwitchStmt - This represents a 'switch' stmt.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isReferenceType() const
bool isVectorType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
This class is used for tools that requires cross translation unit capability.
AnalyzerOptions & options
llvm::ImmutableList< SVal > getEmptySValList()
llvm::ImmutableList< SVal > prependSVal(SVal X, llvm::ImmutableList< SVal > L)
BugReporter is a utility class for generating PathDiagnostics for analysis.
llvm::iterator_range< EQClasses_iterator > equivalenceClasses()
Represents an abstract call to a function or method along a particular path.
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const StackFrame *SF, const CallEvent *Call)
Run checkers for region changes.
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.
void runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, bool AtDeclInit, ExprEngine &Eng, const ProgramPoint &PP)
Run checkers for binding of a value to a location.
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)
Run checkers for end of analysis.
void runCheckersForPrintStateJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\n", unsigned int Space=0, bool IsDot=false) const
Run checkers for debug-printing a ProgramState.
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
void runCheckersForEndFunction(ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS)
Run checkers on end of function.
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
void runCheckersForBlockEntrance(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const BlockEntrance &Entrance, ExprEngine &Eng) const
Run checkers after taking a control flow edge.
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper &SymReaper)=0
Scan all symbols referenced by the constraints.
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
ExplodedNode * makeNode(const ProgramPoint &Loc, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false) const
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...
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void insert(ExplodedNode *N)
const ProgramStateRef & getState() const
pred_iterator pred_begin()
bool isTrivial() const
The node is trivial if it has only one successor, only one predecessor, it's predecessor has only one...
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
ExplodedNode * getFirstSucc()
unsigned succ_size() const
const StackFrame * getStackFrame() const
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
const StackFrame * getRootStackFrame() const
ProgramStateManager & getStateManager()
void processCFGElement(const CFGElement E, ExplodedNode *Pred, unsigned StmtIdx)
processCFGElement - Called by CoreEngine.
void processBranch(const Stmt *Condition, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF, std::optional< unsigned > IterationsCompletedInLoop)
ProcessBranch - Called by CoreEngine.
void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArraySubscriptExpr - Transfer function for array accesses.
void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred)
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const StackFrame *SF, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer's garbage collection - remove dead symbols and bindings from the state.
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
void runCheckersForBlockEntrance(const BlockEntrance &Entrance, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
BasicValueFactory & getBasicVals()
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
void processEndOfFunction(ExplodedNode *Pred, const ReturnStmt *RS=nullptr)
Called by CoreEngine.
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)
void removeDeadOnEndOfFunction(ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
void evalEagerlyAssumeBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex)
evalEagerlyAssumeBifurcation - Given the nodes in 'Src', eagerly assume concrete boolean values for '...
void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for ObjCAtSynchronizedStmts.
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op, SVal LHS, SVal RHS, QualType T)
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred)
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitObjCForCollectionStmt - Transfer function logic for ObjCForCollectionStmt.
void VisitUnaryOperator(const UnaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryOperator - Transfer function logic for unary operators.
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitDeclStmt - Transfer function logic for DeclStmts.
void VisitMSAsmStmt(const MSAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMSAsmStmt - Transfer function logic for MS inline asm.
void processStaticInitializer(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
Called by CoreEngine.
static std::optional< unsigned > getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E, const StackFrame *SF)
Retrieves which element is being constructed in a non-POD type array.
std::string DumpGraph(bool trim=false, StringRef Filename="")
Dump graph to the specified filename.
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const StackFrame *SF, const CallEvent *Call)
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store.
InliningModes
The modes of inlining, which override the default analysis-wide settings.
void printJson(raw_ostream &Out, ProgramStateRef State, const StackFrame *SF, const char *NL, unsigned int Space, bool IsDot) const
printJson - Called by ProgramStateManager to print checker-specific data.
static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const StackFrame *SF)
Retrieves the size of the array in the pending ArrayInitLoopExpr.
ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption)
evalAssume - Callback function invoked by the ConstraintManager when making assumptions about state v...
AnalysisDeclContextManager & getAnalysisDeclContextManager()
static ProgramStateRef removeIterationState(ProgramStateRef State, const ObjCForCollectionStmt *O, const StackFrame *SF)
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
static std::pair< const ProgramPointTag *, const ProgramPointTag * > getEagerlyAssumeBifurcationTags()
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
Called by CoreEngine.
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const StackFrame *SF)
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
StoreManager & getStoreManager()
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
BugReporter & getBugReporter()
void ProcessStmt(const Stmt *S, ExplodedNode *Pred)
ConstCFGElementRef getCFGElementRef() const
ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn)
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion * > ExplicitRegions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits)
Call PointerEscape callback when a value escapes as a result of region invalidation.
static const ProgramPointTag * cleanupNodeTag()
A tag to track convenience transitions, which can be removed at cleanup.
static ProgramStateRef setWhetherHasMoreIteration(ProgramStateRef State, const ObjCForCollectionStmt *O, const StackFrame *SF, bool HasMoreIteraton)
Note whether this loop has any more iterations to model. These methods.
static std::optional< unsigned > getPendingArrayDestruction(ProgramStateRef State, const StackFrame *SF)
Retrieves which element is being destructed in a non-POD type array.
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, ArrayRef< std::pair< SVal, SVal > > LocAndVals, const StackFrame *SF, PointerEscapeKind Kind, const CallEvent *Call)
Call PointerEscape callback when a value escapes as a result of bind.
void ConstructInitList(const Expr *Source, ArrayRef< Expr * > Args, bool IsTransparent, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
ProgramStateRef escapeValues(ProgramStateRef State, ArrayRef< SVal > Vs, PointerEscapeKind K, const CallEvent *Call=nullptr) const
A simple wrapper when you only need to notify checkers of pointer-escape of some values.
void ProcessLoopExit(const Stmt *S, ExplodedNode *Pred)
void processEndWorklist()
Called by CoreEngine when the analysis worklist has terminated.
CheckerManager & getCheckerManager() const
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const StackFrame *SF)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
SymbolManager & getSymbolManager()
void processBeginOfFunction(ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L)
Called by CoreEngine.
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAtomicExpr - Transfer function for builtin atomic expressions.
MemRegionManager & getRegionManager()
void ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for member expressions.
void processSwitch(const SwitchStmt *Switch, ExplodedNode *Pred, ExplodedNodeSet &Dst)
ProcessSwitch - Called by CoreEngine.
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
static bool hasMoreIteration(ProgramStateRef State, const ObjCForCollectionStmt *O, const StackFrame *SF)
bool didEagerlyAssumeBifurcateAt(ProgramStateRef State, const Expr *Ex) const
ConstraintManager & getConstraintManager()
ProgramStateRef getInitialState(const StackFrame *InitSF)
getInitialState - Return the initial state used for the root vertex in the ExplodedGraph.
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
unsigned getNumVisitedCurrent() const
void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitOffsetOfExpr - Transfer function for offsetof.
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.
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
AnalysisManager & getAnalysisManager()
ExplodedGraph & getGraph()
void ProcessDeleteDtor(const CFGDeleteDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
SValBuilder & getSValBuilder()
void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArrayInitLoopExpr - Transfer function for array init loop.
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 processCFGBlockEntrance(const BlockEdge &L, const BlockEntrance &BE, NodeBuilder &Builder, ExplodedNode *Pred)
Called by CoreEngine when processing the entrance of a CFGBlock.
void VisitAttributedStmt(const AttributedStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAttributedStmt - Transfer function logic for AttributedStmt.
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, ExplodedNodeSet &PreVisit, ExplodedNodeSet &Dst)
const StackFrame * getCurrStackFrame() const
Get the 'current' stack frame corresponding to the current work item (elementary analysis step handle...
const CFGBlock * getCurrBlock() const
Get the 'current' CFGBlock corresponding to the current work item (elementary analysis step handled b...
void processIndirectGoto(ExplodedNodeSet &Dst, const Expr *Tgt, const CFGBlock *Dispatch, ExplodedNode *Pred)
processIndirectGoto - Called by CoreEngine.
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
static bool isLocType(QualType T)
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace(ProgramStateRef State) const
Returns the most specific memory space for this memory region in the given ProgramStateRef.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
This is the simplest builder which generates nodes in the ExplodedGraph.
void takeNodes(const ExplodedNodeSet &S)
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Generates a node in the ExplodedGraph.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
void addNodes(const ExplodedNodeSet &S)
While alive, includes the current analysis stack in a crash trace.
Information about invalidation for a particular region/symbol.
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrame *SF)
Return a memory region for the 'this' object reference.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const StackFrame *SF, unsigned count)
Create a new symbol with a unique 'name'.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
bool isUnknownOrUndef() const
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
virtual SVal getLValueField(const FieldDecl *D, SVal Base)
SubRegion - A region that subsets another larger region.
A class responsible for cleaning up unused symbols.
void markLive(SymbolRef sym)
Unconditionally marks a symbol as live.
SymbolicRegion - A special, "non-concrete" region.
Represents symbolic expression that isn't a location.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
@ PSK_DirectEscapeOnCall
The pointer has been passed to a function call directly.
@ PSK_EscapeOnBind
A pointer escapes due to binding its value to a location that the analyzer cannot track.
@ PSK_IndirectEscapeOnCall
The pointer has been passed to a function indirectly.
@ PSK_EscapeOther
The reason for pointer escape is unknown.
DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB, QualType Ty)
llvm::DenseSet< const Decl * > SetOfConstDecls
llvm::DenseSet< SymbolRef > InvalidatedSymbols
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State)
Updates the given ProgramState.
bool isUnrolledState(ProgramStateRef State)
Returns if the given State indicates that is inside a completely unrolled loop.
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState, const StackFrame *SF, unsigned BlockCount, ConstCFGElementRef Elem)
Get the states that result from widening the loop.
void markAllDynamicExtentLive(ProgramStateRef State, SymbolReaper &SymReaper)
ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx, ExplodedNode *Pred, unsigned maxVisitOnPath)
Updates the stack of loops contained by the ProgramState.
bool LE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
@ CXXThis
Parameter for C++ 'this' argument.
Diagnostic wrappers for TextAPI types for error reporting.
Describes how types, statements, expressions, and declarations should be printed.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
Hints for figuring out if a call should be inlined during evalCall().
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
bool IsArrayCtorOrDtor
This call is a constructor or a destructor for a single element within an array, a part of array cons...
Traits for storing the call processing policy inside GDM.
DOTGraphTraits(bool isSimple=false)
static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G)
static bool nodeHasBugReport(const ExplodedNode *N)
static bool traverseHiddenNodes(const ExplodedNode *N, llvm::function_ref< void(const ExplodedNode *)> PreCallback, llvm::function_ref< void(const ExplodedNode *)> PostCallback, llvm::function_ref< bool(const ExplodedNode *)> Stop)
PreCallback: callback before break.
static bool isNodeHidden(const ExplodedNode *N, const ExplodedGraph *G)