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;
1019 llvm::TimeTraceScope TimeScope(
"ExprEngine::removeDead");
1022 &&
"PostStmt is not generally supported by the SymbolReaper yet");
1023 assert(SF &&
"Must pass the current (or expiring) StackFrame");
1025 if (!DiagnosticStmt) {
1026 DiagnosticStmt = ReferenceStmt;
1027 assert(DiagnosticStmt &&
"Required for clearing a StackFrame");
1030 NumRemoveDeadBindings++;
1036 if (!ReferenceStmt) {
1038 "Use PostStmtPurgeDeadSymbolsKind for clearing a StackFrame");
1044 for (
auto I : CleanedState->get<ObjectsUnderConstruction>()) {
1045 if (
SymbolRef Sym = I.second.getAsSymbol())
1047 if (
const MemRegion *MR = I.second.getAsRegion())
1056 CleanedState = StateMgr.removeDeadBindingsFromEnvironmentAndStore(
1057 CleanedState, SF, SymReaper);
1064 DiagnosticStmt, *
this, K);
1074 for (
const auto I : CheckedSet) {
1081 assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->
getState()) &&
1082 "Checkers are not allowed to modify the Environment as a part of "
1083 "checkDeadSymbols processing.");
1084 assert(StateMgr.haveEqualStores(CheckerState, Pred->
getState()) &&
1085 "Checkers are not allowed to modify the Store as a part of "
1086 "checkDeadSymbols processing.");
1091 StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
1094 Out.insert(Engine.makeNode(L, CleanedCheckerSt, I));
1105 G.reclaimRecentlyAllocatedNodes();
1109 "Error evaluating statement");
1116 CleanedStates.
insert(Pred);
1120 for (
const auto I : CleanedStates) {
1123 Visit(currStmt, I, DstI);
1128 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1134 "Error evaluating end of the loop");
1137 if(AMgr.options.ShouldUnrollLoops)
1143 Engine.enqueueStmtNode(N,
getCurrBlock(), currStmtIdx);
1150 "Error evaluating end of a lifetime");
1156 Engine.enqueueStmtNodes(Dst, currBldrCtx->getBlock(), currStmtIdx);
1167 "Error evaluating initializer");
1173 SVal thisVal = State->getSVal(svalBuilder.getCXXThis(
decl, SF));
1185 State = finishObjectConstruction(State, BMI, SF);
1187 Tmp.
insert(Engine.makeNode(PS, State, Pred));
1195 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
1199 if (Field->getType()->isArrayType()) {
1203 while ((ASE = dyn_cast<ArraySubscriptExpr>(
Init)))
1206 InitVal = State->getSVal(
Init, SF);
1215 InitVal = State->getSVal(BMI->
getInit(), SF);
1219 evalBind(Tmp,
Init, Pred, FieldLoc, InitVal,
true, &PP);
1227 SVal InitVal = State->getSVal(
Init, SF);
1228 evalBind(Tmp,
Init, Pred, BaseLoc, InitVal,
true);
1243 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1246std::pair<ProgramStateRef, uint64_t>
1247ExprEngine::prepareStateForArrayDestruction(
const ProgramStateRef State,
1251 SVal *ElementCountVal) {
1252 assert(Region !=
nullptr &&
"Not-null region expected");
1255 while (
const auto *NTy = dyn_cast<ArrayType>(Ty))
1256 Ty = NTy->getElementType().getDesugaredType(
getContext());
1260 if (ElementCountVal)
1261 *ElementCountVal = ElementCount;
1269 if (!ElementCount.isConstant())
1272 Idx = ElementCount.getAsInteger()->getLimitedValue();
1280 return {setPendingArrayDestruction(State, SF, Idx), Idx};
1303 llvm_unreachable(
"Unexpected dtor kind.");
1307 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1318 if (Opts.MayInlineCXXAllocator)
1326 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1332 const auto *DtorDecl = Dtor.getDestructorDecl(
getContext());
1343 const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
1358 std::tie(state, Idx) = prepareStateForArrayDestruction(
1359 state, Region, varType, SF, &ElementCount);
1361 if (ElementCount.isConstant()) {
1362 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1363 assert(ArrayLength &&
1364 "An automatic dtor for a 0 length array shouldn't be triggered!");
1369 "ExprEngine",
"Skipping automatic 0 length array destruction, "
1370 "which shouldn't be in the CFG.");
1373 Engine.makeNode(PP, Pred->
getState(), Pred,
true);
1385 "Prepare for object destruction");
1388 Pred = Engine.makeNode(PP, state, Pred);
1394 false, Pred, Dst, CallOpts);
1405 SVal ArgVal = State->getSVal(Arg, SF);
1409 if (State->isNull(ArgVal).isConstrainedTrue()) {
1419 auto getDtorDecl = [](
const QualType &DTy) {
1431 while (
const auto *AT =
getContext().getAsArrayType(DTy))
1432 DTy = AT->getElementType();
1436 std::tie(State, Idx) =
1437 prepareStateForArrayDestruction(State, ArgR, DTy, SF, &ElementCount);
1441 if (ElementCount.isConstant() &&
1442 ElementCount.getAsInteger()->getLimitedValue() == 0) {
1445 "ExprEngine",
"Skipping 0 length array delete destruction");
1452 ArgR = State->getLValue(DTy, svalBuilder.makeArrayIndex(Idx), ArgVal)
1458 "Prepare for object destruction");
1461 Pred = Engine.makeNode(PP, State, Pred);
1485 true, Pred, Dst, CallOpts);
1498 Loc ThisLoc = State->getSVal(ThisStorageLoc).
castAs<
Loc>();
1499 SVal FieldVal = State->getLValue(
Member, ThisLoc);
1504 std::tie(State, Idx) = prepareStateForArrayDestruction(
1505 State, FieldVal.getAsRegion(),
T, SF, &ElementCount);
1507 if (ElementCount.isConstant()) {
1508 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1509 assert(ArrayLength &&
1510 "A member dtor for a 0 length array shouldn't be triggered!");
1515 "ExprEngine",
"Skipping member 0 length array destruction, which "
1516 "shouldn't be in the CFG.");
1519 Engine.makeNode(PP, Pred->
getState(), Pred,
true);
1530 "Prepare for object destruction");
1533 Pred = Engine.makeNode(PP, State, Pred);
1539 false, Pred, Dst, CallOpts);
1554 State = finishObjectConstruction(State, BTE, SF);
1555 MR =
V->getAsRegion();
1560 if (isDestructorElided(State, BTE, SF)) {
1561 State = cleanupElidedDestructor(State, BTE, SF);
1564 Dst.
insert(Engine.makeNode(PP, State, Pred));
1568 ExplodedNode *CleanPred = Engine.makePostStmtNode(BTE, State, Pred);
1569 if (!CleanPred || CleanPred->
isSink()) {
1599 T = AT->getElementType();
1610 false, CleanPred, Dst, CallOpts);
1622 if (
const CFGBlock *DstBlock = Obj ? DstT : DstF) {
1624 Dst.
insert(Engine.makeNode(BE, State, Pred));
1642 const StackFrame *SF = Node->getStackFrame();
1648 State = addObjectUnderConstruction(State, BTE, SF,
UnknownVal());
1650 Dst.
insert(Engine.makePostStmtNode(BTE, State, Node));
1658 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
1663 : Symbols(Symbols) {}
1667 bool VisitSymbol(
SymbolRef Sym)
override {
1668 Symbols.insert(Sym);
1673 CollectReachableSymbolsCallback CallBack(Symbols);
1675 State->scanReachableSymbols(
V, CallBack);
1678 State, CallBack.getSymbols(),
Call, K,
nullptr);
1690 case Stmt::CXXDependentScopeMemberExprClass:
1691 case Stmt::CXXReflectExprClass:
1692 case Stmt::CXXTryStmtClass:
1693 case Stmt::CXXTypeidExprClass:
1694 case Stmt::CXXUuidofExprClass:
1695 case Stmt::CXXFoldExprClass:
1696 case Stmt::MSPropertyRefExprClass:
1697 case Stmt::MSPropertySubscriptExprClass:
1698 case Stmt::CXXUnresolvedConstructExprClass:
1699 case Stmt::DependentScopeDeclRefExprClass:
1700 case Stmt::ArrayTypeTraitExprClass:
1701 case Stmt::ExpressionTraitExprClass:
1702 case Stmt::UnresolvedLookupExprClass:
1703 case Stmt::UnresolvedMemberExprClass:
1704 case Stmt::RecoveryExprClass:
1705 case Stmt::CXXNoexceptExprClass:
1706 case Stmt::PackExpansionExprClass:
1707 case Stmt::PackIndexingExprClass:
1708 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1709 case Stmt::FunctionParmPackExprClass:
1710 case Stmt::CoroutineBodyStmtClass:
1711 case Stmt::CoawaitExprClass:
1712 case Stmt::DependentCoawaitExprClass:
1713 case Stmt::CoreturnStmtClass:
1714 case Stmt::CoyieldExprClass:
1715 case Stmt::SEHTryStmtClass:
1716 case Stmt::SEHExceptStmtClass:
1717 case Stmt::SEHLeaveStmtClass:
1718 case Stmt::SEHFinallyStmtClass:
1719 case Stmt::CXXExpansionStmtPatternClass:
1720 case Stmt::CXXExpansionStmtInstantiationClass:
1721 case Stmt::CXXExpansionSelectExprClass:
1722 case Stmt::OMPCanonicalLoopClass:
1723 case Stmt::OMPParallelDirectiveClass:
1724 case Stmt::OMPSimdDirectiveClass:
1725 case Stmt::OMPForDirectiveClass:
1726 case Stmt::OMPForSimdDirectiveClass:
1727 case Stmt::OMPSectionsDirectiveClass:
1728 case Stmt::OMPSectionDirectiveClass:
1729 case Stmt::OMPScopeDirectiveClass:
1730 case Stmt::OMPSingleDirectiveClass:
1731 case Stmt::OMPMasterDirectiveClass:
1732 case Stmt::OMPCriticalDirectiveClass:
1733 case Stmt::OMPParallelForDirectiveClass:
1734 case Stmt::OMPParallelForSimdDirectiveClass:
1735 case Stmt::OMPParallelSectionsDirectiveClass:
1736 case Stmt::OMPParallelMasterDirectiveClass:
1737 case Stmt::OMPParallelMaskedDirectiveClass:
1738 case Stmt::OMPTaskDirectiveClass:
1739 case Stmt::OMPTaskyieldDirectiveClass:
1740 case Stmt::OMPBarrierDirectiveClass:
1741 case Stmt::OMPTaskwaitDirectiveClass:
1742 case Stmt::OMPErrorDirectiveClass:
1743 case Stmt::OMPTaskgroupDirectiveClass:
1744 case Stmt::OMPFlushDirectiveClass:
1745 case Stmt::OMPDepobjDirectiveClass:
1746 case Stmt::OMPScanDirectiveClass:
1747 case Stmt::OMPOrderedDirectiveClass:
1748 case Stmt::OMPAtomicDirectiveClass:
1749 case Stmt::OMPAssumeDirectiveClass:
1750 case Stmt::OMPTargetDirectiveClass:
1751 case Stmt::OMPTargetDataDirectiveClass:
1752 case Stmt::OMPTargetEnterDataDirectiveClass:
1753 case Stmt::OMPTargetExitDataDirectiveClass:
1754 case Stmt::OMPTargetParallelDirectiveClass:
1755 case Stmt::OMPTargetParallelForDirectiveClass:
1756 case Stmt::OMPTargetUpdateDirectiveClass:
1757 case Stmt::OMPTeamsDirectiveClass:
1758 case Stmt::OMPCancellationPointDirectiveClass:
1759 case Stmt::OMPCancelDirectiveClass:
1760 case Stmt::OMPTaskLoopDirectiveClass:
1761 case Stmt::OMPTaskLoopSimdDirectiveClass:
1762 case Stmt::OMPMasterTaskLoopDirectiveClass:
1763 case Stmt::OMPMaskedTaskLoopDirectiveClass:
1764 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
1765 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
1766 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
1767 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
1768 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1769 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
1770 case Stmt::OMPDistributeDirectiveClass:
1771 case Stmt::OMPDistributeParallelForDirectiveClass:
1772 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1773 case Stmt::OMPDistributeSimdDirectiveClass:
1774 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1775 case Stmt::OMPTargetSimdDirectiveClass:
1776 case Stmt::OMPTeamsDistributeDirectiveClass:
1777 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1778 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1779 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1780 case Stmt::OMPTargetTeamsDirectiveClass:
1781 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1782 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1783 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1784 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1785 case Stmt::OMPReverseDirectiveClass:
1786 case Stmt::OMPStripeDirectiveClass:
1787 case Stmt::OMPTileDirectiveClass:
1788 case Stmt::OMPInterchangeDirectiveClass:
1789 case Stmt::OMPSplitDirectiveClass:
1790 case Stmt::OMPFuseDirectiveClass:
1791 case Stmt::OMPInteropDirectiveClass:
1792 case Stmt::OMPDispatchDirectiveClass:
1793 case Stmt::OMPMaskedDirectiveClass:
1794 case Stmt::OMPGenericLoopDirectiveClass:
1795 case Stmt::OMPTeamsGenericLoopDirectiveClass:
1796 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
1797 case Stmt::OMPParallelGenericLoopDirectiveClass:
1798 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
1799 case Stmt::CapturedStmtClass:
1800 case Stmt::SYCLKernelCallStmtClass:
1801 case Stmt::UnresolvedSYCLKernelCallStmtClass:
1802 case Stmt::OpenACCComputeConstructClass:
1803 case Stmt::OpenACCLoopConstructClass:
1804 case Stmt::OpenACCCombinedConstructClass:
1805 case Stmt::OpenACCDataConstructClass:
1806 case Stmt::OpenACCEnterDataConstructClass:
1807 case Stmt::OpenACCExitDataConstructClass:
1808 case Stmt::OpenACCHostDataConstructClass:
1809 case Stmt::OpenACCWaitConstructClass:
1810 case Stmt::OpenACCCacheConstructClass:
1811 case Stmt::OpenACCInitConstructClass:
1812 case Stmt::OpenACCShutdownConstructClass:
1813 case Stmt::OpenACCSetConstructClass:
1814 case Stmt::OpenACCUpdateConstructClass:
1815 case Stmt::OpenACCAtomicConstructClass:
1816 case Stmt::OMPUnrollDirectiveClass:
1817 case Stmt::OMPMetaDirectiveClass:
1818 case Stmt::HLSLOutArgExprClass: {
1825 case Stmt::ParenExprClass:
1826 llvm_unreachable(
"ParenExprs already handled.");
1827 case Stmt::GenericSelectionExprClass:
1828 llvm_unreachable(
"GenericSelectionExprs already handled.");
1831 case Stmt::BreakStmtClass:
1832 case Stmt::CaseStmtClass:
1833 case Stmt::CompoundStmtClass:
1834 case Stmt::ContinueStmtClass:
1835 case Stmt::CXXForRangeStmtClass:
1836 case Stmt::DefaultStmtClass:
1837 case Stmt::DoStmtClass:
1838 case Stmt::ForStmtClass:
1839 case Stmt::GotoStmtClass:
1840 case Stmt::IfStmtClass:
1841 case Stmt::IndirectGotoStmtClass:
1842 case Stmt::LabelStmtClass:
1844 case Stmt::NullStmtClass:
1845 case Stmt::SwitchStmtClass:
1846 case Stmt::WhileStmtClass:
1847 case Stmt::DeferStmtClass:
1848 case Expr::MSDependentExistsStmtClass:
1849 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
1850 case Stmt::ImplicitValueInitExprClass:
1854 llvm_unreachable(
"Should be pruned from CFG");
1856 case Stmt::ObjCSubscriptRefExprClass:
1857 case Stmt::ObjCPropertyRefExprClass:
1858 llvm_unreachable(
"These are handled by PseudoObjectExpr");
1860 case Stmt::GNUNullExprClass: {
1862 SVal Val = svalBuilder.makeIntValWithWidth(
getContext().VoidPtrTy, 0);
1867 case Stmt::ObjCAtSynchronizedStmtClass:
1871 case Expr::ConstantExprClass:
1872 case Stmt::ExprWithCleanupsClass:
1877 case Stmt::CXXBindTemporaryExprClass: {
1886 case Stmt::ArrayInitLoopExprClass:
1890 case Stmt::DesignatedInitExprClass:
1891 case Stmt::DesignatedInitUpdateExprClass:
1892 case Stmt::ArrayInitIndexExprClass:
1893 case Stmt::ExtVectorElementExprClass:
1894 case Stmt::MatrixElementExprClass:
1895 case Stmt::ImaginaryLiteralClass:
1896 case Stmt::ObjCAtCatchStmtClass:
1897 case Stmt::ObjCAtFinallyStmtClass:
1898 case Stmt::ObjCAtTryStmtClass:
1899 case Stmt::ObjCAutoreleasePoolStmtClass:
1900 case Stmt::ObjCEncodeExprClass:
1901 case Stmt::ObjCIsaExprClass:
1902 case Stmt::ObjCProtocolExprClass:
1903 case Stmt::ObjCSelectorExprClass:
1904 case Stmt::ParenListExprClass:
1905 case Stmt::ShuffleVectorExprClass:
1906 case Stmt::ConvertVectorExprClass:
1907 case Stmt::VAArgExprClass:
1908 case Stmt::CUDAKernelCallExprClass:
1909 case Stmt::OpaqueValueExprClass:
1910 case Stmt::AsTypeExprClass:
1911 case Stmt::ConceptSpecializationExprClass:
1912 case Stmt::CXXRewrittenBinaryOperatorClass:
1913 case Stmt::RequiresExprClass:
1914 case Stmt::EmbedExprClass:
1919 case Stmt::PredefinedExprClass:
1920 case Stmt::AddrLabelExprClass:
1921 case Stmt::IntegerLiteralClass:
1922 case Stmt::FixedPointLiteralClass:
1923 case Stmt::CharacterLiteralClass:
1924 case Stmt::CXXScalarValueInitExprClass:
1925 case Stmt::CXXBoolLiteralExprClass:
1926 case Stmt::ObjCBoolLiteralExprClass:
1927 case Stmt::ObjCAvailabilityCheckExprClass:
1928 case Stmt::FloatingLiteralClass:
1929 case Stmt::NoInitExprClass:
1930 case Stmt::SizeOfPackExprClass:
1931 case Stmt::StringLiteralClass:
1932 case Stmt::SourceLocExprClass:
1933 case Stmt::ObjCStringLiteralClass:
1934 case Stmt::CXXPseudoDestructorExprClass:
1935 case Stmt::SubstNonTypeTemplateParmExprClass:
1936 case Stmt::CXXNullPtrLiteralExprClass:
1937 case Stmt::ArraySectionExprClass:
1938 case Stmt::OMPArrayShapingExprClass:
1939 case Stmt::OMPIteratorExprClass:
1940 case Stmt::SYCLUniqueStableNameExprClass:
1941 case Stmt::OpenACCAsteriskSizeExprClass:
1942 case Stmt::TypeTraitExprClass: {
1949 case Stmt::AttributedStmtClass: {
1954 case Stmt::CXXDefaultArgExprClass:
1955 case Stmt::CXXDefaultInitExprClass: {
1962 if (
const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
1963 ArgE = DefE->getExpr();
1964 else if (
const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
1965 ArgE = DefE->getExpr();
1967 llvm_unreachable(
"unknown constant wrapper kind");
1969 bool IsTemporary =
false;
1970 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
1971 ArgE = MTE->getSubExpr();
1975 std::optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
1980 for (
const auto I : PreVisit) {
1982 State = State->BindExpr(
cast<Expr>(S), SF, *ConstantVal);
1984 State = createTemporaryRegionIfNeeded(State, SF,
cast<Expr>(S),
1986 Tmp.
insert(Engine.makePostStmtNode(S, State, I));
1994 case Stmt::CXXStdInitializerListExprClass:
1995 case Expr::ObjCArrayLiteralClass:
1996 case Expr::ObjCDictionaryLiteralClass:
1997 case Expr::ObjCBoxedExprClass: {
2004 QualType resultType = Ex->getType();
2006 for (
const auto N : preVisit) {
2008 SVal result = svalBuilder.conjureSymbolVal(
2018 for (
auto Child : Ex->children()) {
2020 const auto *ChildExpr = dyn_cast<Expr>(Child);
2021 SVal Val = ChildExpr ? State->getSVal(ChildExpr, SF) :
UnknownVal();
2025 Tmp.
insert(Engine.makePostStmtNode(S, State, N));
2032 case Stmt::ArraySubscriptExprClass:
2036 case Stmt::MatrixSingleSubscriptExprClass:
2038 "Support for MatrixSingleSubscriptExprClass is not implemented.");
2041 case Stmt::MatrixSubscriptExprClass:
2042 llvm_unreachable(
"Support for MatrixSubscriptExpr is not implemented.");
2045 case Stmt::GCCAsmStmtClass: {
2055 case Stmt::MSAsmStmtClass:
2059 case Stmt::BlockExprClass:
2063 case Stmt::LambdaExprClass:
2064 if (AMgr.options.ShouldInlineLambdas) {
2073 case Stmt::BinaryOperatorClass: {
2075 if (B->isLogicalOp()) {
2078 }
else if (B->getOpcode() == BO_Comma) {
2081 Dst.
insert(Engine.makeNodeWithBinding(Pred, B, Val));
2085 if (AMgr.options.ShouldEagerlyAssume &&
2086 (B->isRelationalOp() || B->isEqualityOp())) {
2097 case Stmt::CXXOperatorCallExprClass:
2098 case Stmt::CallExprClass:
2099 case Stmt::CXXMemberCallExprClass:
2100 case Stmt::UserDefinedLiteralClass:
2104 case Stmt::CXXCatchStmtClass:
2108 case Stmt::CXXTemporaryObjectExprClass:
2109 case Stmt::CXXConstructExprClass:
2113 case Stmt::CXXInheritedCtorInitExprClass:
2118 case Stmt::CXXNewExprClass: {
2124 for (
const auto i : PreVisit)
2131 case Stmt::CXXDeleteExprClass: {
2138 for (
const auto i : PostVisit)
2146 case Stmt::ChooseExprClass: {
2152 case Stmt::CompoundAssignOperatorClass:
2156 case Stmt::CompoundLiteralExprClass:
2160 case Stmt::BinaryConditionalOperatorClass:
2161 case Stmt::ConditionalOperatorClass: {
2167 case Stmt::CXXThisExprClass:
2171 case Stmt::DeclRefExprClass: {
2177 case Stmt::DeclStmtClass:
2181 case Stmt::ImplicitCastExprClass:
2182 case Stmt::CStyleCastExprClass:
2183 case Stmt::CXXStaticCastExprClass:
2184 case Stmt::CXXDynamicCastExprClass:
2185 case Stmt::CXXReinterpretCastExprClass:
2186 case Stmt::CXXConstCastExprClass:
2187 case Stmt::CXXFunctionalCastExprClass:
2188 case Stmt::BuiltinBitCastExprClass:
2189 case Stmt::ObjCBridgedCastExprClass:
2190 case Stmt::CXXAddrspaceCastExprClass: {
2200 case Expr::MaterializeTemporaryExprClass: {
2205 for (
const auto i : dstPrevisit)
2211 case Stmt::InitListExprClass: {
2217 case Expr::CXXParenListInitExprClass: {
2224 case Stmt::MemberExprClass:
2228 case Stmt::AtomicExprClass:
2232 case Stmt::ObjCIvarRefExprClass:
2236 case Stmt::ObjCForCollectionStmtClass:
2240 case Stmt::ObjCMessageExprClass:
2244 case Stmt::ObjCAtThrowStmtClass:
2245 case Stmt::CXXThrowExprClass:
2248 Engine.makePostStmtNode(S, Pred->
getState(), Pred,
true);
2251 case Stmt::ReturnStmtClass:
2255 case Stmt::OffsetOfExprClass: {
2260 for (
const auto Node : PreVisit)
2267 case Stmt::UnaryExprOrTypeTraitExprClass:
2272 case Stmt::StmtExprClass: {
2275 if (SE->getSubStmt()->body_empty()) {
2278 &&
"Empty statement expression must have void type.");
2279 }
else if (
const auto *LastExpr =
2280 dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
2282 Pred = Engine.makeNodeWithBinding(Pred, SE, Val);
2288 case Stmt::UnaryOperatorClass: {
2290 if (AMgr.options.ShouldEagerlyAssume && (
U->getOpcode() == UO_LNot)) {
2300 case Stmt::PseudoObjectExprClass: {
2303 if (
const Expr *
Result = PE->getResultExpr())
2305 Dst.
insert(Engine.makeNodeWithBinding(Pred, PE,
V));
2309 case Expr::ObjCIndirectCopyRestoreExprClass: {
2314 const Expr *E = OIE->getSubExpr();
2316 Dst.
insert(Engine.makeNodeWithBinding(Pred, OIE,
V));
2325 assert(CalleeSF && CallerSF);
2332 BeforeProcessingCall = N;
2347 if (SP->getStmt() == CE)
2352 if (!BeforeProcessingCall)
2388 NumTimesRetriedWithoutInlining++;
2402 if(AMgr.options.ShouldUnrollLoops) {
2403 unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
2407 Pred, maxBlockVisitOnPath);
2408 if (NewState != Pred->
getState()) {
2409 ExplodedNode *UpdatedNode = Builder.generateNode(BE, NewState, Pred);
2423 if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
2424 AMgr.options.ShouldWidenLoops) {
2426 if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
2440 Builder.generateNode(BE, WidenedState, Pred);
2445 if (BlockCount >= AMgr.options.maxBlockVisitOnPath) {
2449 Builder.generateSink(TaggedLoc, Pred->
getState(), Pred);
2462 Engine.FunctionSummaries->markShouldNotInline(SF->
getDecl());
2468 if ((!AMgr.options.NoRetryExhausted && replayWithoutInlining(Pred, SF)))
2470 NumMaxBlockCountReachedInInlined++;
2472 NumMaxBlockCountReached++;
2475 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
2482 llvm::PrettyStackTraceFormat CrashInfo(
2483 "Processing block entrance B%d -> B%d",
2501 const auto *Ex = dyn_cast<Expr>(
Condition);
2506 bool bitsInit =
false;
2508 while (
const auto *CE = dyn_cast<CastExpr>(Ex)) {
2511 if (!
T->isIntegralOrEnumerationType())
2515 if (!bitsInit || newBits < bits) {
2520 Ex = CE->getSubExpr();
2526 if (!bitsInit || !
T->isIntegralOrEnumerationType() ||
2530 return state->getSVal(Ex, SF);
2536 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2537 if (!BO || !BO->isLogicalOp()) {
2540 Condition = BO->getRHS()->IgnoreParens();
2562 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2565 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2566 if (!BO || !BO->isLogicalOp())
2570 "Other kinds of branches are handled separately!");
2581 std::optional<CFGStmt> CS = Elem.getAs<
CFGStmt>();
2584 const Stmt *LastStmt = CS->getStmt();
2588 llvm_unreachable(
"could not resolve condition");
2592 std::pair<const ObjCForCollectionStmt *, const StackFrame *>;
2598 bool HasMoreIteraton) {
2599 assert(!State->contains<ObjCForHasMoreIterations>({O, SF}));
2600 return State->set<ObjCForHasMoreIterations>({O, SF}, HasMoreIteraton);
2606 assert(State->contains<ObjCForHasMoreIterations>({O, SF}));
2607 return State->remove<ObjCForHasMoreIterations>({O, SF});
2613 assert(State->contains<ObjCForHasMoreIterations>({O, SF}));
2614 return *State->get<ObjCForHasMoreIterations>({O, SF});
2620static std::optional<std::pair<ProgramStateRef, ProgramStateRef>>
2623 if (
const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(ConditionStmt)) {
2624 bool HasMoreIteraton =
2631 if (HasMoreIteraton)
2632 return std::pair<ProgramStateRef, ProgramStateRef>{State,
nullptr};
2634 return std::pair<ProgramStateRef, ProgramStateRef>{
nullptr, State};
2637 const auto *ConditionExpr = dyn_cast<Expr>(ConditionStmt);
2638 assert(ConditionExpr &&
"The condition must be an Expr from here!");
2642 if (
X.isUnknownOrUndef()) {
2644 if (
const auto *Ex = dyn_cast<Expr>(ConditionExpr)) {
2645 if (Ex->getType()->isIntegralOrEnumerationType()) {
2652 N->
getState()->getStateManager().getContext());
2662 if (
X.isUnknownOrUndef())
2663 return std::nullopt;
2667 return State->assume(
V);
2673 std::optional<unsigned> IterationsCompletedInLoop) {
2675 "CXXBindTemporaryExprs are handled by processBindTemporary.");
2691 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2697 "Error evaluating branch");
2703 if (CheckersOutSet.
empty())
2711 std::tie(StTrue, StFalse) = *KnownCondValueAssumption;
2713 if (StTrue && StFalse)
2724 (StTrue && StFalse) ||
2743 bool CompletedTwoIterations = IterationsCompletedInLoop.value_or(0) >= 2;
2744 bool SkipTrueBranch = BothFeasible && CompletedTwoIterations;
2750 if (!SkipTrueBranch || AMgr.options.ShouldWidenLoops) {
2753 Dst.
insert(Engine.makeNode(BE, StTrue, PredN));
2755 }
else if (!AMgr.options.InlineFunctionsWithAmbiguousLoops) {
2772 Engine.FunctionSummaries->markShouldNotInline(SF->
getDecl());
2790 bool BeforeFirstIteration = IterationsCompletedInLoop == std::optional{0};
2791 bool SkipFalseBranch = BothFeasible && BeforeFirstIteration &&
2792 AMgr.options.ShouldAssumeAtLeastOneIteration;
2793 if (!SkipFalseBranch && DstF) {
2795 Dst.
insert(Engine.makeNode(BE, StFalse, PredN));
2804 llvm::ImmutableSet<const VarDecl *>)
2813 bool InitHasRun = State->contains<InitializedGlobalsSet>(VD);
2815 State = State->add<InitializedGlobalsSet>(VD);
2817 if (
const CFGBlock *DstBlock = InitHasRun ? DstT : DstF) {
2851 Dst.
insert(Engine.makeNode(BE, State, Pred));
2869 State = finishArgumentConstruction(
2884 while (SF != ToSF) {
2885 assert(SF &&
"ToSF must be a parent of FromSF!");
2886 for (
auto I : State->get<ObjectsUnderConstruction>())
2887 if (I.first.getStackFrame() == SF) {
2891 assert(I.first.getItem().getKind() ==
2893 I.first.getItem().getKind() ==
2895 State = State->remove<ObjectsUnderConstruction>(I.first);
2903 Pred = Engine.makeNode(Pred->
getLocation(), State, Pred);
2920 for (
const auto I : AfterRemovedDead)
2926 Engine.enqueueEndOfFunction(Dst, RS);
2940 assert(SwitchBlock->
succ_size() &&
"Switch must have at least one successor");
2946 llvm::iterator_range<CFGBlock::const_succ_reverse_iterator> CaseBlocks(
2953 Condition->IgnoreParens(), CheckersOutSet, Pred, *
this);
2963 std::optional<NonLoc> CondNL = CondV.
getAs<
NonLoc>();
2965 for (
const CFGBlock *CaseBlock : CaseBlocks) {
2974 assert(V1.getBitWidth() ==
2980 V2 = E->EvaluateKnownConstInt(ACtx);
2987 std::tie(StateMatching, State) =
2988 State->assumeInclusiveRange(*CondNL, V1, V2);
2992 StateMatching = State;
2995 if (StateMatching) {
2996 BlockEdge BE(SwitchBlock, CaseBlock, SF);
2997 Dst.
insert(Engine.makeNode(BE, StateMatching, Node));
3019 if (
Condition->IgnoreParenImpCasts()->getType()->isEnumeralType()) {
3020 if (
Switch->isAllEnumCasesCovered())
3024 BlockEdge BE(SwitchBlock, DefaultBlock, SF);
3025 Dst.
insert(Engine.makeNode(BE, State, Node));
3039 auto resolveAsLambdaCapturedVar =
3040 [&](
const ValueDecl *VD) -> std::optional<std::pair<SVal, QualType>> {
3041 const auto *MD = dyn_cast<CXXMethodDecl>(SF->
getDecl());
3042 const auto *DeclRefEx = dyn_cast<DeclRefExpr>(Ex);
3043 if (AMgr.options.ShouldInlineLambdas && DeclRefEx &&
3044 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
3045 MD->getParent()->isLambda()) {
3048 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
3054 if (
const FieldDecl *FD = LambdaCaptureFields[VD]) {
3055 Loc CXXThis = svalBuilder.getCXXThis(MD, SF);
3057 return std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
3061 return std::nullopt;
3064 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
3067 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
3068 std::optional<std::pair<SVal, QualType>> VInfo =
3069 resolveAsLambdaCapturedVar(VD);
3072 VInfo = std::make_pair(state->getLValue(VD, SF), VD->getType());
3074 SVal V = VInfo->first;
3075 bool IsReference = VInfo->second->isReferenceType();
3081 V = state->getSVal(R);
3090 if (
const auto *ED = dyn_cast<EnumConstantDecl>(D)) {
3092 SVal V = svalBuilder.makeIntVal(ED->getInitVal());
3093 Dst.
insert(Engine.makeNodeWithBinding(Pred, Ex,
V));
3096 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
3097 SVal V = svalBuilder.getFunctionPointer(FD);
3108 if (
const auto *BD = dyn_cast<BindingDecl>(D)) {
3110 if (std::optional<std::pair<SVal, QualType>> VInfo =
3111 resolveAsLambdaCapturedVar(BD)) {
3112 auto [
V,
T] = VInfo.value();
3114 if (
T->isReferenceType()) {
3116 V = state->getSVal(R);
3121 Dst.
insert(Engine.makeNodeWithBinding(Pred, Ex,
V,
3128 SVal Base = state->getLValue(DD, SF);
3129 if (DD->getType()->isReferenceType()) {
3131 Base = state->getSVal(R);
3139 if (
const auto *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
3141 V = state->getLValue(Field,
Base);
3144 else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BD->getBinding())) {
3145 SVal Idx = state->getSVal(ASE->getIdx(), SF);
3150 assert(Idx.
isConstant() &&
"BindingDecl array index is not a constant!");
3152 V = state->getLValue(BD->getType(), Idx,
Base);
3155 else if (
const auto *HV = BD->getHoldingVar()) {
3156 V = state->getLValue(HV, SF);
3158 if (HV->getType()->isReferenceType()) {
3160 V = state->getSVal(R);
3165 llvm_unreachable(
"An unknown case of structured binding encountered!");
3169 if (BD->getType()->isReferenceType() && !BD->getHoldingVar()) {
3171 V = state->getSVal(R);
3181 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
3188 llvm_unreachable(
"Support for this Decl not implemented.");
3204 EvalSet.
insert(CheckerPreStmt);
3205 CheckerPreStmt.
clear();
3208 for (
auto *Node : CheckerPreStmt) {
3209 const StackFrame *SF = Node->getStackFrame();
3248 if (
const auto *ME = dyn_cast<MemberExpr>(Arr)) {
3249 Expr *MEBase = ME->getBase();
3252 if (
auto CXXSCE = dyn_cast<CXXStaticCastExpr>(MEBase)) {
3253 MEBase = CXXSCE->getSubExpr();
3274 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arr))
3279 Base = state->getSVal(R);
3283 EvalSet.
insert(Engine.makeNodeWithBinding(Node, Ex,
Base));
3307 (A->
getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
3309 for (
auto *Node : CheckerPreStmt) {
3310 const StackFrame *SF = Node->getStackFrame();
3313 if (IsGLValueLike) {
3319 if (
T->isVoidType())
3322 SVal V = state->getLValue(
T, state->getSVal(Idx, SF),
3323 state->getSVal(
Base, SF));
3326 }
else if (IsVectorType) {
3328 EvalSet.
insert(Engine.makePostStmtNode(A, state, Node));
3330 llvm_unreachable(
"Array subscript should be an lValue when not \
3331a vector and not a forbidden lvalue type");
3351 for (
const auto I : CheckedSet)
3356 for (
const auto I : CheckedSet) {
3362 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member)) {
3363 if (MD->isImplicitObjectMemberFunction())
3364 state = createTemporaryRegionIfNeeded(state, SF, BaseExpr);
3366 SVal MDVal = svalBuilder.getFunctionPointer(MD);
3368 EvalSet.
insert(Engine.makeNodeWithBinding(I, M, MDVal, state));
3374 state = createTemporaryRegionIfNeeded(state, SF, BaseExpr,
3381 if (
const auto *SR =
3382 dyn_cast_or_null<SymbolicRegion>(baseExprVal.
getAsRegion())) {
3383 QualType T = SR->getPointeeStaticType();
3389 SVal L = state->getLValue(field, baseExprVal);
3399 dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
3400 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
3401 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
3405 if (field->getType()->isReferenceType()) {
3407 L = state->getSVal(R);
3412 EvalSet.
insert(Engine.makeNodeWithBinding(
3436 for (
const auto I : AfterPreSet) {
3443 ValuesToInvalidate.push_back(SubExprVal);
3451 AfterInvalidateSet.
insert(
3452 Engine.makeNodeWithBinding(I, AE,
UnknownVal(), State));
3469 for (
const std::pair<SVal, SVal> &LocAndVal : LocAndVals) {
3471 const MemRegion *MR = LocAndVal.first.getAsRegion();
3474 Escaped.push_back(LocAndVal.second);
3479 if (
const auto *VR = dyn_cast<VarRegion>(MR->
getBaseRegion()))
3481 VR->getStackFrame()->inTopFrame())
3482 if (
const auto *RD = VR->getValueType()->getAsCXXRecordDecl())
3483 if (!RD->hasTrivialDestructor()) {
3484 Escaped.push_back(LocAndVal.second);
3493 SVal StoredVal = State->getSVal(MR);
3494 if (StoredVal != LocAndVal.second)
3497 Escaped.push_back(LocAndVal.second);
3500 if (Escaped.empty())
3509 std::pair<SVal, SVal> LocAndVal(
Loc, Val);
3520 if (!Invalidated || Invalidated->empty())
3533 for (
const auto I : ExplicitRegions) {
3535 SymbolsDirectlyInvalidated.insert(R->getSymbol());
3539 for (
const auto &sym : *Invalidated) {
3540 if (SymbolsDirectlyInvalidated.count(sym))
3542 SymbolsIndirectlyInvalidated.insert(sym);
3545 if (!SymbolsDirectlyInvalidated.empty())
3550 if (!SymbolsIndirectlyInvalidated.empty())
3564 assert(!
isa<NonLoc>(Location) &&
"evalBind location should not be NonLoc!");
3575 StoreE, AtDeclInit, *
this, *PP);
3583 if (
auto AsLoc = Location.getAs<
Loc>()) {
3587 State = State->bindLoc(*AsLoc, Val, SF, !AtDeclInit);
3590 PostStore PS(StoreE, SF, Location.getAsRegion(),
nullptr);
3604 const Expr *LocationE,
3610 const Expr *StoreE = AssignE ? AssignE : LocationE;
3614 evalLocation(Tmp, AssignE, LocationE, Pred, state, location,
false);
3622 for (
const auto I : Tmp)
3623 evalBind(Dst, StoreE, I, location, Val,
false);
3628 const Expr *BoundEx,
3634 assert(!
isa<NonLoc>(location) &&
"location cannot be a NonLoc.");
3639 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location,
true);
3648 for (
const auto I : Tmp) {
3649 state = I->getState();
3655 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
3659 state->BindExpr(BoundEx, I->getStackFrame(),
V), tag,
3666 const Stmt *BoundEx,
3678 BldrTop.takeNodes(Pred);
3691 Bldr.generateNode(NodeEx, Pred, state, &tag);
3695 NodeEx, BoundEx, *
this);
3696 BldrTop.addNodes(Tmp);
3699std::pair<const ProgramPointTag *, const ProgramPointTag *>
3702 FalseTag(TagProviderName,
"Eagerly Assume False");
3704 return std::make_pair(&TrueTag, &FalseTag);
3728 State = State->set<LastEagerlyAssumeExprIfSuccessful>(
nullptr);
3729 SVal V = State->getSVal(Ex, SF);
3731 if (SEV && SEV->isExpression()) {
3734 auto [StateTrue, StateFalse] = State->assume(*SEV);
3736 if (StateTrue && StateFalse) {
3737 StateTrue = StateTrue->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3738 StateFalse = StateFalse->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3744 StateTrue = StateTrue->BindExpr(Ex, SF, Val);
3745 PostStmt PostStmtTrue(Ex, SF, TrueTag);
3752 StateFalse = StateFalse->BindExpr(Ex, SF, Val);
3753 PostStmt PostStmtFalse(Ex, SF, FalseTag);
3763 const Expr *Ex)
const {
3764 return Ex && State->get<LastEagerlyAssumeExprIfSuccessful>() == Ex;
3782 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3793 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3800 Dst.
insert(Engine.makePostStmtNode(A, state, Pred));
3823 for (
const auto &
Report : Class.getReports()) {
3824 const auto *PR = dyn_cast<PathSensitiveBugReport>(
Report.get());
3842 llvm::function_ref<
void(
const ExplodedNode *)> PreCallback,
3843 llvm::function_ref<
void(
const ExplodedNode *)> PostCallback,
3865 llvm::raw_string_ostream Out(Buf);
3867 const bool IsDot =
true;
3868 const unsigned int Space = 1;
3871 Out <<
"{ \"state_id\": " << State->getID()
3874 Indent(Out, Space, IsDot) <<
"\"program_points\": [\\l";
3880 Indent(Out, Space + 1, IsDot) <<
"{ ";
3882 Out <<
", \"tag\": ";
3884 Out <<
'\"' << Tag->getDebugTag() <<
'\"';
3887 Out <<
", \"node_id\": " << OtherNode->
getID() <<
3888 ", \"is_sink\": " << OtherNode->
isSink() <<
3896 Indent(Out, Space, IsDot) <<
"],\\l";
3909 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
3913 std::string Filename =
DumpGraph(Nodes);
3914 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
3919 std::vector<const ExplodedNode *> Src;
3922 for (
const auto &
Class : BR.equivalenceClasses()) {
3924 dyn_cast<PathSensitiveBugReport>(
Class.getReports()[0].get());
3927 const auto *N =
const_cast<ExplodedNode *
>(R->getErrorNode());
3934 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
3935 return llvm::WriteGraph(&G,
"ExprEngine",
false,
3937 std::string(Filename));
3941 StringRef Filename) {
3942 std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
3945 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
3950 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
3951 return llvm::WriteGraph(TrimmedG.get(),
"TrimmedExprEngine",
3953 "Trimmed Exploded Graph",
3954 std::string(Filename));
3958 static int index = 0;
3962void ExprEngine::anchor() { }
3974 bool IsCompound =
T->isArrayType() ||
T->isRecordType() ||
3975 T->isAnyComplexType() ||
T->isVectorType();
3978 if (Args.size() > 1 || (E->
isPRValue() && IsCompound && !IsTransparent)) {
3980 for (
Expr *E : llvm::reverse(Args))
3984 }
else if (Args.size() == 0) {
3987 Val = S->getSVal(Args.front(), SF);
3989 Dst.
insert(Engine.makeNodeWithBinding(Pred, E, Val));
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,...
const CFGBlock * getPreviousBlock() const
const CFGBlock * getBlock() const
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
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.
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 the lifetime of an automatic object ends.
const VarDecl * getVarDecl() 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
LLVM_ATTRIBUTE_RETURNS_NONNULL const Stmt * getTriggerStmt() 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 the lifetime of an automatic object ends.
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.
void runCheckersForLifetimeEnd(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const VarDecl *Decl, ExprEngine &Eng)
Run checkers for the end of a variable's lifetime.
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.
void ProcessLifetimeEnd(const Stmt *S, const VarDecl *D, ExplodedNode *Pred)
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.
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Generates a node in the ExplodedGraph.
While alive, includes the current analysis stack in a crash trace.
Information about invalidation for a particular region/symbol.
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
NonLoc makeCompoundVal(QualType type, llvm::ImmutableList< SVal > vals)
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.
const FunctionProtoType * T
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)