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/ADT/Statistic.h"
71#include "llvm/Support/Casting.h"
72#include "llvm/Support/Compiler.h"
73#include "llvm/Support/DOTGraphTraits.h"
74#include "llvm/Support/ErrorHandling.h"
75#include "llvm/Support/GraphWriter.h"
76#include "llvm/Support/SaveAndRestore.h"
77#include "llvm/Support/raw_ostream.h"
90#define DEBUG_TYPE "ExprEngine"
93 "The # of times RemoveDeadBindings is called");
95 "The # of aborted paths due to reaching the maximum block count in "
96 "a top level function");
98 "The # of aborted paths due to reaching the maximum block count in "
99 "an inlined function");
101 "The # of times we re-evaluated a call without inlining");
122class ConstructedObjectKey {
123 using ConstructedObjectKeyImpl =
124 std::pair<ConstructionContextItem, const LocationContext *>;
125 const ConstructedObjectKeyImpl Impl;
133 const LocationContext *getLocationContext()
const {
return Impl.second; }
136 return getLocationContext()->getDecl()->getASTContext();
139 void printJson(llvm::raw_ostream &Out,
PrinterHelper *Helper,
141 const Stmt *S = getItem().getStmtOrNull();
144 I = getItem().getCXXCtorInitializer();
147 Out <<
"\"stmt_id\": " << S->getID(getASTContext());
149 Out <<
"\"init_id\": " << I->
getID(getASTContext());
152 Out <<
", \"kind\": \"" << getItem().getKindAsString()
153 <<
"\", \"argument_index\": ";
156 Out << getItem().getIndex();
161 Out <<
", \"pretty\": ";
164 S->printJson(Out, Helper, PP,
true);
170 void Profile(llvm::FoldingSetNodeID &ID)
const {
172 ID.AddPointer(Impl.second);
175 bool operator==(
const ConstructedObjectKey &RHS)
const {
176 return Impl == RHS.Impl;
179 bool operator<(
const ConstructedObjectKey &RHS)
const {
180 return Impl < RHS.Impl;
185typedef llvm::ImmutableMap<ConstructedObjectKey, SVal>
196typedef llvm::ImmutableMap<
197 std::pair<const CXXConstructExpr *, const LocationContext *>,
unsigned>
198 IndexOfElementToConstructMap;
200 IndexOfElementToConstructMap)
205typedef llvm::ImmutableMap<
206 std::pair<const CXXConstructExpr *, const LocationContext *>,
unsigned>
210typedef llvm::ImmutableMap<const LocationContext *, unsigned>
219static const char* TagProviderName =
"ExprEngine";
224 : CTU(CTU), IsCTUEnabled(mgr.getAnalyzerOptions().IsNaiveCTUEnabled),
225 AMgr(mgr), AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
226 Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.getGraph()),
227 StateMgr(getContext(), mgr.getStoreManagerCreator(),
228 mgr.getConstraintManagerCreator(), G.getAllocator(), this),
229 SymMgr(StateMgr.getSymbolManager()), MRMgr(StateMgr.getRegionManager()),
230 svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
231 BR(mgr, *this), VisitedCallees(VisitedCalleesIn),
232 HowToInline(HowToInlineIn) {
233 unsigned TrimInterval = mgr.
options.GraphTrimInterval;
234 if (TrimInterval != 0) {
252 if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
256 if (!II || !(II->
getName() ==
"main" && FD->getNumParams() > 0))
261 const auto *BT = dyn_cast<BuiltinType>(
T);
262 if (!BT || !BT->isInteger())
265 const MemRegion *R = state->getRegion(PD, InitLoc);
274 std::optional<DefinedOrUnknownSVal> Constraint =
287 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(
D)) {
291 const MemRegion *R = state->getRegion(SelfD, InitLoc);
294 if (std::optional<Loc> LV =
V.getAs<
Loc>()) {
296 state = state->assume(*LV,
true);
297 assert(state &&
"'self' cannot be null");
301 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D)) {
302 if (MD->isImplicitObjectMemberFunction()) {
309 SVal V = state->getSVal(L);
310 if (std::optional<Loc> LV =
V.getAs<
Loc>()) {
311 state = state->assume(*LV,
true);
312 assert(state &&
"'this' cannot be null");
324 const SubRegion **OutRegionWithAdjustments) {
330 SVal InitValWithAdjustments = State->getSVal(InitWithAdjustments, LC);
334 if (!isa<NonLoc>(InitValWithAdjustments)) {
335 if (OutRegionWithAdjustments)
336 *OutRegionWithAdjustments =
nullptr;
339 Result = InitWithAdjustments;
343 assert(!isa<Loc>(InitValWithAdjustments) ||
345 Result->getType()->isMemberPointerType());
377 CommaLHSs, Adjustments);
385 if (
const auto *MT = dyn_cast<MaterializeTemporaryExpr>(
Result)) {
387 State = finishObjectConstruction(State, MT, LC);
388 State = State->BindExpr(
Result, LC, *
V);
390 }
else if (
const ValueDecl *VD = MT->getExtendingDecl()) {
422 State = State->invalidateRegions(Reg, InitWithAdjustments,
424 nullptr,
nullptr,
nullptr);
437 SVal InitVal = State->getSVal(
Init, LC);
441 State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
445 if (InitValWithAdjustments.
isUnknown()) {
453 State->bindLoc(Reg.
castAs<
Loc>(), InitValWithAdjustments, LC,
false);
455 State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
461 if (
Result->isGLValue()) {
462 State = State->BindExpr(
Result, LC, Reg);
464 State = State->BindExpr(
Result, LC, InitValWithAdjustments);
470 if (OutRegionWithAdjustments)
471 *OutRegionWithAdjustments = cast<SubRegion>(Reg.
getAsRegion());
480 assert(!State->contains<IndexOfElementToConstruct>(Key) || Idx > 0);
482 return State->set<IndexOfElementToConstruct>(Key, Idx);
485std::optional<unsigned>
488 const unsigned *
V = State->get<PendingInitLoop>({
E, LCtx->
getStackFrame()});
489 return V ? std::make_optional(*
V) : std::nullopt;
497 assert(
E && State->contains<PendingInitLoop>(Key));
498 return State->remove<PendingInitLoop>(Key);
507 assert(!State->contains<PendingInitLoop>(Key) && Size > 0);
509 return State->set<PendingInitLoop>(Key, Size);
512std::optional<unsigned>
517 State->get<IndexOfElementToConstruct>({
E, LCtx->
getStackFrame()});
518 return V ? std::make_optional(*
V) : std::nullopt;
527 assert(
E && State->contains<IndexOfElementToConstruct>(Key));
528 return State->remove<IndexOfElementToConstruct>(Key);
531std::optional<unsigned>
534 assert(LCtx &&
"LocationContext shouldn't be null!");
538 return V ? std::make_optional(*
V) : std::nullopt;
543 assert(LCtx &&
"LocationContext shouldn't be null!");
547 return State->set<PendingArrayDestruction>(Key, Idx);
553 assert(LCtx &&
"LocationContext shouldn't be null!");
557 assert(LCtx && State->contains<PendingArrayDestruction>(Key));
558 return State->remove<PendingArrayDestruction>(Key);
569 if (
auto DS = dyn_cast_or_null<DeclStmt>(Item.
getStmtOrNull())) {
570 if (
auto VD = dyn_cast_or_null<VarDecl>(DS->getSingleDecl()))
571 Init = VD->getInit();
574 if (
auto LE = dyn_cast_or_null<LambdaExpr>(Item.
getStmtOrNull()))
583 if (
const auto *AILE = dyn_cast_or_null<ArrayInitLoopExpr>(
Init))
592 assert((!State->get<ObjectsUnderConstruction>(Key) ||
593 Key.getItem().getKind() ==
595 State->contains<IndexOfElementToConstruct>(
596 {dyn_cast_or_null<CXXConstructExpr>(Init), LC})) &&
597 "The object is already marked as `UnderConstruction`, when it's not "
599 return State->set<ObjectsUnderConstruction>(Key,
V);
607 const SVal *
V = State->get<ObjectsUnderConstruction>(Key);
608 return V ? std::make_optional(*
V) : std::nullopt;
616 assert(State->contains<ObjectsUnderConstruction>(Key));
617 return State->remove<ObjectsUnderConstruction>(Key);
623 ConstructedObjectKey Key({BTE,
true}, LC);
626 return State->set<ObjectsUnderConstruction>(Key,
UnknownVal());
633 ConstructedObjectKey Key({BTE,
true}, LC);
634 assert(State->contains<ObjectsUnderConstruction>(Key));
635 return State->remove<ObjectsUnderConstruction>(Key);
641 ConstructedObjectKey Key({BTE,
true}, LC);
642 return State->contains<ObjectsUnderConstruction>(Key);
650 assert(LC &&
"ToLC must be a parent of FromLC!");
651 for (
auto I : State->get<ObjectsUnderConstruction>())
652 if (I.first.getLocationContext() == LC)
668 SVal cond,
bool assumption) {
687 unsigned int Space = 0,
bool IsDot =
false) {
692 bool HasItem =
false;
695 const ConstructedObjectKey *LastKey =
nullptr;
696 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
697 const ConstructedObjectKey &Key = I.first;
698 if (Key.getLocationContext() != LCtx)
709 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
710 const ConstructedObjectKey &Key = I.first;
712 if (Key.getLocationContext() != LCtx)
715 Indent(Out, Space, IsDot) <<
"{ ";
716 Key.printJson(Out,
nullptr, PP);
717 Out <<
", \"value\": \"" <<
Value <<
"\" }";
725 Indent(Out, --Space, IsDot) <<
']';
733 const LocationContext *LCtx,
unsigned int Space = 0,
bool IsDot =
false) {
734 using KeyT = std::pair<const Expr *, const LocationContext *>;
740 bool HasItem =
false;
744 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
745 const KeyT &Key = I.first;
746 if (Key.second != LCtx)
757 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
758 const KeyT &Key = I.first;
759 unsigned Value = I.second;
760 if (Key.second != LCtx)
763 Indent(Out, Space, IsDot) <<
"{ ";
766 const Expr *
E = Key.first;
767 Out <<
"\"stmt_id\": " <<
E->
getID(Context);
770 Out <<
", \"kind\": null";
773 Out <<
", \"pretty\": ";
779 Out <<
", \"value\": \"Current index: " <<
Value - 1 <<
"\" }";
787 Indent(Out, --Space, IsDot) <<
']';
796 unsigned int Space = 0,
797 bool IsDot =
false) {
798 using KeyT = std::pair<const CXXConstructExpr *, const LocationContext *>;
804 bool HasItem =
false;
808 for (
const auto &I : State->get<PendingInitLoop>()) {
809 const KeyT &Key = I.first;
810 if (Key.second != LCtx)
821 for (
const auto &I : State->get<PendingInitLoop>()) {
822 const KeyT &Key = I.first;
823 unsigned Value = I.second;
824 if (Key.second != LCtx)
827 Indent(Out, Space, IsDot) <<
"{ ";
830 Out <<
"\"stmt_id\": " <<
E->
getID(Context);
832 Out <<
", \"kind\": null";
833 Out <<
", \"pretty\": ";
839 Out <<
", \"value\": \"Flattened size: " <<
Value <<
"\"}";
847 Indent(Out, --Space, IsDot) <<
']';
856 unsigned int Space = 0,
bool IsDot =
false) {
860 bool HasItem =
false;
863 KeyT LastKey =
nullptr;
864 for (
const auto &I : State->get<PendingArrayDestruction>()) {
865 const KeyT &Key = I.first;
877 for (
const auto &I : State->get<PendingArrayDestruction>()) {
878 const KeyT &Key = I.first;
882 Indent(Out, Space, IsDot) <<
"{ ";
884 Out <<
"\"stmt_id\": null";
885 Out <<
", \"kind\": null";
886 Out <<
", \"pretty\": \"Current index: \"";
887 Out <<
", \"value\": \"" << I.second <<
"\" }";
895 Indent(Out, --Space, IsDot) <<
']';
909template <
typename Trait,
typename Printer,
typename... Args>
912 const char *NL,
unsigned int Space,
bool IsDot,
913 const char *jsonPropertyName, Printer printer, Args &&...args) {
921 static_assert(std::is_function_v<std::remove_pointer_t<Printer>>,
922 "Printer is not a function!");
923 static_assert(std::is_convertible_v<Printer, RequiredType>,
924 "Printer doesn't have the required type!");
926 if (LCtx && !State->get<Trait>().isEmpty()) {
927 Indent(Out, Space, IsDot) <<
'\"' << jsonPropertyName <<
"\": ";
931 printer(Out, State, NL, LC, Space, IsDot, std::forward<Args>(args)...);
935 Indent(Out, Space, IsDot) <<
"]," << NL;
941 unsigned int Space,
bool IsDot)
const {
943 printStateTraitWithLocationContextJson<ObjectsUnderConstruction>(
944 Out, State, LCtx, NL, Space, IsDot,
"constructing_objects",
946 printStateTraitWithLocationContextJson<IndexOfElementToConstruct>(
947 Out, State, LCtx, NL, Space, IsDot,
"index_of_element",
949 printStateTraitWithLocationContextJson<PendingInitLoop>(
950 Out, State, LCtx, NL, Space, IsDot,
"pending_init_loops",
952 printStateTraitWithLocationContextJson<PendingArrayDestruction>(
953 Out, State, LCtx, NL, Space, IsDot,
"pending_destructors",
969 currStmtIdx = StmtIdx;
972 switch (
E.getKind()) {
1030 const Stmt *ReferenceStmt,
1032 const Stmt *DiagnosticStmt,
1035 ReferenceStmt ==
nullptr || isa<ReturnStmt>(ReferenceStmt))
1036 &&
"PostStmt is not generally supported by the SymbolReaper yet");
1037 assert(LC &&
"Must pass the current (or expiring) LocationContext");
1039 if (!DiagnosticStmt) {
1040 DiagnosticStmt = ReferenceStmt;
1041 assert(DiagnosticStmt &&
"Required for clearing a LocationContext");
1044 NumRemoveDeadBindings++;
1050 if (!ReferenceStmt) {
1052 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
1059 for (
auto I : CleanedState->get<ObjectsUnderConstruction>()) {
1060 if (
SymbolRef Sym = I.second.getAsSymbol())
1062 if (
const MemRegion *MR = I.second.getAsRegion())
1072 CleanedState, SFC, SymReaper);
1081 DiagnosticStmt, *
this, K);
1087 for (
const auto I : CheckedSet) {
1095 "Checkers are not allowed to modify the Environment as a part of "
1096 "checkDeadSymbols processing.");
1098 "Checkers are not allowed to modify the Store as a part of "
1099 "checkDeadSymbols processing.");
1105 Bldr.
generateNode(DiagnosticStmt, I, CleanedCheckerSt, &cleanupTag, K);
1115 "Error evaluating statement");
1124 CleanedStates.
Add(Pred);
1128 for (
const auto I : CleanedStates) {
1131 Visit(currStmt, I, DstI);
1142 "Error evaluating end of the loop");
1148 if(AMgr.
options.ShouldUnrollLoops)
1165 "Error evaluating initializer");
1169 const auto *
decl = cast<CXXConstructorDecl>(stackFrame->getDecl());
1184 State = finishObjectConstruction(State, BMI, LC);
1195 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
1199 if (
Init->getType()->isArrayType()) {
1203 while ((ASE = dyn_cast<ArraySubscriptExpr>(
Init)))
1206 SVal LValue = State->getSVal(
Init, stackFrame);
1207 if (!Field->getType()->isReferenceType())
1208 if (std::optional<Loc> LValueLoc = LValue.
getAs<
Loc>())
1209 InitVal = State->getSVal(*LValueLoc);
1219 InitVal = State->getSVal(BMI->
getInit(), stackFrame);
1223 evalBind(Tmp,
Init, Pred, FieldLoc, InitVal,
true, &PP);
1231 SVal InitVal = State->getSVal(
Init, stackFrame);
1232 evalBind(Tmp,
Init, Pred, BaseLoc, InitVal,
true);
1244 for (
const auto I : Tmp) {
1253std::pair<ProgramStateRef, uint64_t>
1254ExprEngine::prepareStateForArrayDestruction(
const ProgramStateRef State,
1258 SVal *ElementCountVal) {
1259 assert(Region !=
nullptr &&
"Not-null region expected");
1262 while (
const auto *NTy = dyn_cast<ArrayType>(Ty))
1263 Ty = NTy->getElementType().getDesugaredType(
getContext());
1267 if (ElementCountVal)
1268 *ElementCountVal = ElementCount;
1276 if (!ElementCount.isConstant())
1279 Idx = ElementCount.getAsInteger()->getLimitedValue();
1287 return {setPendingArrayDestruction(State, LCtx, Idx), Idx};
1310 llvm_unreachable(
"Unexpected dtor kind.");
1325 if (Opts.MayInlineCXXAllocator)
1351 const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
1360 varType = cast<TypedValueRegion>(Region)->getValueType();
1364 if (isa<ArrayType>(varType)) {
1366 std::tie(state, Idx) = prepareStateForArrayDestruction(
1367 state, Region, varType, LCtx, &ElementCount);
1370 uint64_t ArrayLength = ElementCount.
getAsInteger()->getLimitedValue();
1371 assert(ArrayLength &&
1372 "An automatic dtor for a 0 length array shouldn't be triggered!");
1377 "ExprEngine",
"Skipping automatic 0 length array destruction, "
1378 "which shouldn't be in the CFG.");
1396 "Prepare for object destruction");
1406 false, Pred, Dst, CallOpts);
1417 SVal ArgVal = State->getSVal(Arg, LCtx);
1421 if (State->isNull(ArgVal).isConstrainedTrue()) {
1432 auto getDtorDecl = [](
const QualType &DTy) {
1445 DTy = AT->getElementType();
1449 std::tie(State, Idx) = prepareStateForArrayDestruction(
1450 State, ArgR, DTy, LCtx, &ElementCount);
1458 "ExprEngine",
"Skipping 0 length array delete destruction");
1466 ArgR = State->getLValue(DTy, svalBuilder.
makeArrayIndex(Idx), ArgVal)
1473 "Prepare for object destruction");
1489 const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->
getDecl());
1502 true, Pred, Dst, CallOpts);
1507 const auto *DtorDecl =
D.getDestructorDecl(
getContext());
1513 const auto *CurDtor = cast<CXXDestructorDecl>(LCtx->
getDecl());
1514 Loc ThisStorageLoc =
1516 Loc ThisLoc = State->getSVal(ThisStorageLoc).castAs<
Loc>();
1517 SVal FieldVal = State->getLValue(
Member, ThisLoc);
1520 if (isa<ArrayType>(
T)) {
1522 std::tie(State, Idx) = prepareStateForArrayDestruction(
1523 State, FieldVal.getAsRegion(),
T, LCtx, &ElementCount);
1526 uint64_t ArrayLength = ElementCount.
getAsInteger()->getLimitedValue();
1527 assert(ArrayLength &&
1528 "A member dtor for a 0 length array shouldn't be triggered!");
1533 "ExprEngine",
"Skipping member 0 length array destruction, which "
1534 "shouldn't be in the CFG.");
1551 "Prepare for object destruction");
1561 false, Pred, Dst, CallOpts);
1577 State = finishObjectConstruction(State,
D.getBindTemporaryExpr(),
1579 MR =
V->getAsRegion();
1584 if (isDestructorElided(State, BTE, LC)) {
1585 State = cleanupElidedDestructor(State, BTE, LC);
1596 StmtBldr.
generateNode(
D.getBindTemporaryExpr(), Pred, State);
1598 QualType T =
D.getBindTemporaryExpr()->getSubExpr()->getType();
1601 assert(CleanDtorState.
size() <= 1);
1603 CleanDtorState.
empty() ? Pred : *CleanDtorState.
begin();
1626 T = AT->getElementType();
1637 false, CleanPred, Dst, CallOpts);
1679 State = addObjectUnderConstruction(State, BTE, LC,
UnknownVal());
1689 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
1694 : Symbols(Symbols) {}
1698 bool VisitSymbol(
SymbolRef Sym)
override {
1699 Symbols.insert(Sym);
1704 CollectReachableSymbolsCallback CallBack(Symbols);
1706 State->scanReachableSymbols(
V, CallBack);
1709 State, CallBack.getSymbols(),
Call, K,
nullptr);
1715 S->getBeginLoc(),
"Error evaluating statement");
1719 assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
1721 switch (S->getStmtClass()) {
1723 case Stmt::CXXDependentScopeMemberExprClass:
1724 case Stmt::CXXTryStmtClass:
1725 case Stmt::CXXTypeidExprClass:
1726 case Stmt::CXXUuidofExprClass:
1727 case Stmt::CXXFoldExprClass:
1728 case Stmt::MSPropertyRefExprClass:
1729 case Stmt::MSPropertySubscriptExprClass:
1730 case Stmt::CXXUnresolvedConstructExprClass:
1731 case Stmt::DependentScopeDeclRefExprClass:
1732 case Stmt::ArrayTypeTraitExprClass:
1733 case Stmt::ExpressionTraitExprClass:
1734 case Stmt::UnresolvedLookupExprClass:
1735 case Stmt::UnresolvedMemberExprClass:
1736 case Stmt::TypoExprClass:
1737 case Stmt::RecoveryExprClass:
1738 case Stmt::CXXNoexceptExprClass:
1739 case Stmt::PackExpansionExprClass:
1740 case Stmt::PackIndexingExprClass:
1741 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1742 case Stmt::FunctionParmPackExprClass:
1743 case Stmt::CoroutineBodyStmtClass:
1744 case Stmt::CoawaitExprClass:
1745 case Stmt::DependentCoawaitExprClass:
1746 case Stmt::CoreturnStmtClass:
1747 case Stmt::CoyieldExprClass:
1748 case Stmt::SEHTryStmtClass:
1749 case Stmt::SEHExceptStmtClass:
1750 case Stmt::SEHLeaveStmtClass:
1751 case Stmt::SEHFinallyStmtClass:
1752 case Stmt::OMPCanonicalLoopClass:
1753 case Stmt::OMPParallelDirectiveClass:
1754 case Stmt::OMPSimdDirectiveClass:
1755 case Stmt::OMPForDirectiveClass:
1756 case Stmt::OMPForSimdDirectiveClass:
1757 case Stmt::OMPSectionsDirectiveClass:
1758 case Stmt::OMPSectionDirectiveClass:
1759 case Stmt::OMPScopeDirectiveClass:
1760 case Stmt::OMPSingleDirectiveClass:
1761 case Stmt::OMPMasterDirectiveClass:
1762 case Stmt::OMPCriticalDirectiveClass:
1763 case Stmt::OMPParallelForDirectiveClass:
1764 case Stmt::OMPParallelForSimdDirectiveClass:
1765 case Stmt::OMPParallelSectionsDirectiveClass:
1766 case Stmt::OMPParallelMasterDirectiveClass:
1767 case Stmt::OMPParallelMaskedDirectiveClass:
1768 case Stmt::OMPTaskDirectiveClass:
1769 case Stmt::OMPTaskyieldDirectiveClass:
1770 case Stmt::OMPBarrierDirectiveClass:
1771 case Stmt::OMPTaskwaitDirectiveClass:
1772 case Stmt::OMPErrorDirectiveClass:
1773 case Stmt::OMPTaskgroupDirectiveClass:
1774 case Stmt::OMPFlushDirectiveClass:
1775 case Stmt::OMPDepobjDirectiveClass:
1776 case Stmt::OMPScanDirectiveClass:
1777 case Stmt::OMPOrderedDirectiveClass:
1778 case Stmt::OMPAtomicDirectiveClass:
1779 case Stmt::OMPAssumeDirectiveClass:
1780 case Stmt::OMPTargetDirectiveClass:
1781 case Stmt::OMPTargetDataDirectiveClass:
1782 case Stmt::OMPTargetEnterDataDirectiveClass:
1783 case Stmt::OMPTargetExitDataDirectiveClass:
1784 case Stmt::OMPTargetParallelDirectiveClass:
1785 case Stmt::OMPTargetParallelForDirectiveClass:
1786 case Stmt::OMPTargetUpdateDirectiveClass:
1787 case Stmt::OMPTeamsDirectiveClass:
1788 case Stmt::OMPCancellationPointDirectiveClass:
1789 case Stmt::OMPCancelDirectiveClass:
1790 case Stmt::OMPTaskLoopDirectiveClass:
1791 case Stmt::OMPTaskLoopSimdDirectiveClass:
1792 case Stmt::OMPMasterTaskLoopDirectiveClass:
1793 case Stmt::OMPMaskedTaskLoopDirectiveClass:
1794 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
1795 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
1796 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
1797 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
1798 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1799 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
1800 case Stmt::OMPDistributeDirectiveClass:
1801 case Stmt::OMPDistributeParallelForDirectiveClass:
1802 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1803 case Stmt::OMPDistributeSimdDirectiveClass:
1804 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1805 case Stmt::OMPTargetSimdDirectiveClass:
1806 case Stmt::OMPTeamsDistributeDirectiveClass:
1807 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1808 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1809 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1810 case Stmt::OMPTargetTeamsDirectiveClass:
1811 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1812 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1813 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1814 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1815 case Stmt::OMPReverseDirectiveClass:
1816 case Stmt::OMPTileDirectiveClass:
1817 case Stmt::OMPInterchangeDirectiveClass:
1818 case Stmt::OMPInteropDirectiveClass:
1819 case Stmt::OMPDispatchDirectiveClass:
1820 case Stmt::OMPMaskedDirectiveClass:
1821 case Stmt::OMPGenericLoopDirectiveClass:
1822 case Stmt::OMPTeamsGenericLoopDirectiveClass:
1823 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
1824 case Stmt::OMPParallelGenericLoopDirectiveClass:
1825 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
1826 case Stmt::CapturedStmtClass:
1827 case Stmt::OpenACCComputeConstructClass:
1828 case Stmt::OpenACCLoopConstructClass:
1829 case Stmt::OMPUnrollDirectiveClass:
1830 case Stmt::OMPMetaDirectiveClass: {
1836 case Stmt::ParenExprClass:
1837 llvm_unreachable(
"ParenExprs already handled.");
1838 case Stmt::GenericSelectionExprClass:
1839 llvm_unreachable(
"GenericSelectionExprs already handled.");
1842 case Stmt::BreakStmtClass:
1843 case Stmt::CaseStmtClass:
1844 case Stmt::CompoundStmtClass:
1845 case Stmt::ContinueStmtClass:
1846 case Stmt::CXXForRangeStmtClass:
1847 case Stmt::DefaultStmtClass:
1848 case Stmt::DoStmtClass:
1849 case Stmt::ForStmtClass:
1850 case Stmt::GotoStmtClass:
1851 case Stmt::IfStmtClass:
1852 case Stmt::IndirectGotoStmtClass:
1853 case Stmt::LabelStmtClass:
1855 case Stmt::NullStmtClass:
1856 case Stmt::SwitchStmtClass:
1857 case Stmt::WhileStmtClass:
1858 case Expr::MSDependentExistsStmtClass:
1859 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
1860 case Stmt::ImplicitValueInitExprClass:
1864 llvm_unreachable(
"Should be pruned from CFG");
1866 case Stmt::ObjCSubscriptRefExprClass:
1867 case Stmt::ObjCPropertyRefExprClass:
1868 llvm_unreachable(
"These are handled by PseudoObjectExpr");
1870 case Stmt::GNUNullExprClass: {
1873 state = state->BindExpr(
1880 case Stmt::ObjCAtSynchronizedStmtClass:
1886 case Expr::ConstantExprClass:
1887 case Stmt::ExprWithCleanupsClass:
1891 case Stmt::CXXBindTemporaryExprClass: {
1902 case Stmt::ArrayInitLoopExprClass:
1908 case Stmt::DesignatedInitExprClass:
1909 case Stmt::DesignatedInitUpdateExprClass:
1910 case Stmt::ArrayInitIndexExprClass:
1911 case Stmt::ExtVectorElementExprClass:
1912 case Stmt::ImaginaryLiteralClass:
1913 case Stmt::ObjCAtCatchStmtClass:
1914 case Stmt::ObjCAtFinallyStmtClass:
1915 case Stmt::ObjCAtTryStmtClass:
1916 case Stmt::ObjCAutoreleasePoolStmtClass:
1917 case Stmt::ObjCEncodeExprClass:
1918 case Stmt::ObjCIsaExprClass:
1919 case Stmt::ObjCProtocolExprClass:
1920 case Stmt::ObjCSelectorExprClass:
1921 case Stmt::ParenListExprClass:
1922 case Stmt::ShuffleVectorExprClass:
1923 case Stmt::ConvertVectorExprClass:
1924 case Stmt::VAArgExprClass:
1925 case Stmt::CUDAKernelCallExprClass:
1926 case Stmt::OpaqueValueExprClass:
1927 case Stmt::AsTypeExprClass:
1928 case Stmt::ConceptSpecializationExprClass:
1929 case Stmt::CXXRewrittenBinaryOperatorClass:
1930 case Stmt::RequiresExprClass:
1931 case Expr::CXXParenListInitExprClass:
1936 case Stmt::PredefinedExprClass:
1937 case Stmt::AddrLabelExprClass:
1938 case Stmt::AttributedStmtClass:
1939 case Stmt::IntegerLiteralClass:
1940 case Stmt::FixedPointLiteralClass:
1941 case Stmt::CharacterLiteralClass:
1942 case Stmt::CXXScalarValueInitExprClass:
1943 case Stmt::CXXBoolLiteralExprClass:
1944 case Stmt::ObjCBoolLiteralExprClass:
1945 case Stmt::ObjCAvailabilityCheckExprClass:
1946 case Stmt::FloatingLiteralClass:
1947 case Stmt::NoInitExprClass:
1948 case Stmt::SizeOfPackExprClass:
1949 case Stmt::StringLiteralClass:
1950 case Stmt::SourceLocExprClass:
1951 case Stmt::ObjCStringLiteralClass:
1952 case Stmt::CXXPseudoDestructorExprClass:
1953 case Stmt::SubstNonTypeTemplateParmExprClass:
1954 case Stmt::CXXNullPtrLiteralExprClass:
1955 case Stmt::ArraySectionExprClass:
1956 case Stmt::OMPArrayShapingExprClass:
1957 case Stmt::OMPIteratorExprClass:
1958 case Stmt::SYCLUniqueStableNameExprClass:
1959 case Stmt::TypeTraitExprClass: {
1968 case Stmt::CXXDefaultArgExprClass:
1969 case Stmt::CXXDefaultInitExprClass: {
1978 if (
const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
1979 ArgE = DefE->getExpr();
1980 else if (
const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
1981 ArgE = DefE->getExpr();
1983 llvm_unreachable(
"unknown constant wrapper kind");
1985 bool IsTemporary =
false;
1986 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
1987 ArgE = MTE->getSubExpr();
1991 std::optional<SVal> ConstantVal = svalBuilder.
getConstantVal(ArgE);
1996 for (
const auto I : PreVisit) {
1998 State = State->BindExpr(S, LCtx, *ConstantVal);
2000 State = createTemporaryRegionIfNeeded(State, LCtx,
2012 case Stmt::CXXStdInitializerListExprClass:
2013 case Expr::ObjCArrayLiteralClass:
2014 case Expr::ObjCDictionaryLiteralClass:
2015 case Expr::ObjCBoxedExprClass: {
2024 const auto *Ex = cast<Expr>(S);
2025 QualType resultType = Ex->getType();
2027 for (
const auto N : preVisit) {
2036 if (!(isa<ObjCBoxedExpr>(Ex) &&
2037 !cast<ObjCBoxedExpr>(Ex)->getSubExpr()
2039 for (
auto Child : Ex->children()) {
2041 SVal Val = State->getSVal(Child, LCtx);
2053 case Stmt::ArraySubscriptExprClass:
2059 case Stmt::MatrixSubscriptExprClass:
2060 llvm_unreachable(
"Support for MatrixSubscriptExpr is not implemented.");
2063 case Stmt::GCCAsmStmtClass: {
2075 case Stmt::MSAsmStmtClass:
2081 case Stmt::BlockExprClass:
2087 case Stmt::LambdaExprClass:
2088 if (AMgr.
options.ShouldInlineLambdas) {
2098 case Stmt::BinaryOperatorClass: {
2099 const auto *B = cast<BinaryOperator>(S);
2100 if (B->isLogicalOp()) {
2106 else if (B->getOpcode() == BO_Comma) {
2110 state->getSVal(B->getRHS(),
2117 if (AMgr.
options.ShouldEagerlyAssume &&
2118 (B->isRelationalOp() || B->isEqualityOp())) {
2130 case Stmt::CXXOperatorCallExprClass: {
2131 const auto *OCE = cast<CXXOperatorCallExpr>(S);
2135 const Decl *Callee = OCE->getCalleeDecl();
2136 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
2137 if (MD->isImplicitObjectMemberFunction()) {
2141 createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
2142 if (NewState != State) {
2154 case Stmt::CallExprClass:
2155 case Stmt::CXXMemberCallExprClass:
2156 case Stmt::UserDefinedLiteralClass:
2162 case Stmt::CXXCatchStmtClass:
2168 case Stmt::CXXTemporaryObjectExprClass:
2169 case Stmt::CXXConstructExprClass:
2175 case Stmt::CXXInheritedCtorInitExprClass:
2182 case Stmt::CXXNewExprClass: {
2189 for (
const auto i : PreVisit)
2197 case Stmt::CXXDeleteExprClass: {
2200 const auto *CDE = cast<CXXDeleteExpr>(S);
2214 case Stmt::ChooseExprClass: {
2216 const auto *
C = cast<ChooseExpr>(S);
2222 case Stmt::CompoundAssignOperatorClass:
2228 case Stmt::CompoundLiteralExprClass:
2234 case Stmt::BinaryConditionalOperatorClass:
2235 case Stmt::ConditionalOperatorClass: {
2237 const auto *
C = cast<AbstractConditionalOperator>(S);
2243 case Stmt::CXXThisExprClass:
2249 case Stmt::DeclRefExprClass: {
2251 const auto *DE = cast<DeclRefExpr>(S);
2257 case Stmt::DeclStmtClass:
2263 case Stmt::ImplicitCastExprClass:
2264 case Stmt::CStyleCastExprClass:
2265 case Stmt::CXXStaticCastExprClass:
2266 case Stmt::CXXDynamicCastExprClass:
2267 case Stmt::CXXReinterpretCastExprClass:
2268 case Stmt::CXXConstCastExprClass:
2269 case Stmt::CXXFunctionalCastExprClass:
2270 case Stmt::BuiltinBitCastExprClass:
2271 case Stmt::ObjCBridgedCastExprClass:
2272 case Stmt::CXXAddrspaceCastExprClass: {
2274 const auto *
C = cast<CastExpr>(S);
2284 case Expr::MaterializeTemporaryExprClass: {
2286 const auto *MTE = cast<MaterializeTemporaryExpr>(S);
2290 for (
const auto i : dstPrevisit)
2297 case Stmt::InitListExprClass:
2303 case Stmt::MemberExprClass:
2309 case Stmt::AtomicExprClass:
2315 case Stmt::ObjCIvarRefExprClass:
2321 case Stmt::ObjCForCollectionStmtClass:
2327 case Stmt::ObjCMessageExprClass:
2333 case Stmt::ObjCAtThrowStmtClass:
2334 case Stmt::CXXThrowExprClass:
2340 case Stmt::ReturnStmtClass:
2346 case Stmt::OffsetOfExprClass: {
2352 for (
const auto Node : PreVisit)
2360 case Stmt::UnaryExprOrTypeTraitExprClass:
2367 case Stmt::StmtExprClass: {
2368 const auto *SE = cast<StmtExpr>(S);
2370 if (SE->getSubStmt()->body_empty()) {
2373 &&
"Empty statement expression must have void type.");
2377 if (
const auto *LastExpr =
2378 dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
2382 state->getSVal(LastExpr,
2388 case Stmt::UnaryOperatorClass: {
2390 const auto *
U = cast<UnaryOperator>(S);
2391 if (AMgr.
options.ShouldEagerlyAssume && (
U->getOpcode() == UO_LNot)) {
2402 case Stmt::PseudoObjectExprClass: {
2405 const auto *PE = cast<PseudoObjectExpr>(S);
2406 if (
const Expr *
Result = PE->getResultExpr()) {
2420 case Expr::ObjCIndirectCopyRestoreExprClass: {
2426 const auto *OIE = cast<ObjCIndirectCopyRestoreExpr>(S);
2427 const Expr *
E = OIE->getSubExpr();
2435 case Stmt::EmbedExprClass:
2436 llvm::report_fatal_error(
"Support for EmbedExpr is not implemented.");
2445 assert(CalleeSF && CallerSF);
2452 BeforeProcessingCall = N;
2467 if (SP->getStmt() == CE)
2472 if (!BeforeProcessingCall)
2501 NumTimesRetriedWithoutInlining++;
2512 if(AMgr.
options.ShouldUnrollLoops) {
2517 Pred, maxBlockVisitOnPath);
2518 if (NewState != Pred->
getState()) {
2534 AMgr.
options.ShouldWidenLoops) {
2536 if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
2557 (*G.
roots_begin())->getLocation().getLocationContext();
2566 replayWithoutInlining(Pred, CalleeLC)))
2568 NumMaxBlockCountReachedInInlined++;
2570 NumMaxBlockCountReached++;
2573 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
2591 const auto *Ex = dyn_cast<Expr>(
Condition);
2596 bool bitsInit =
false;
2598 while (
const auto *CE = dyn_cast<CastExpr>(Ex)) {
2605 if (!bitsInit || newBits < bits) {
2610 Ex = CE->getSubExpr();
2620 return state->getSVal(Ex, LCtx);
2626 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2627 if (!BO || !BO->isLogicalOp()) {
2630 Condition = BO->getRHS()->IgnoreParens();
2652 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2655 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2656 if (!BO || !BO->isLogicalOp())
2660 "Other kinds of branches are handled separately!");
2671 std::optional<CFGStmt> CS = Elem.getAs<
CFGStmt>();
2674 const Stmt *LastStmt = CS->getStmt();
2678 llvm_unreachable(
"could not resolve condition");
2682 std::pair<const ObjCForCollectionStmt *, const LocationContext *>;
2689 assert(!State->contains<ObjCForHasMoreIterations>({O, LC}));
2690 return State->set<ObjCForHasMoreIterations>({O, LC}, HasMoreIteraton);
2697 assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
2698 return State->remove<ObjCForHasMoreIterations>({O, LC});
2704 assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
2705 return *State->get<ObjCForHasMoreIterations>({O, LC});
2711static std::optional<std::pair<ProgramStateRef, ProgramStateRef>>
2714 if (
const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(
Condition)) {
2715 bool HasMoreIteraton =
2722 if (HasMoreIteraton)
2723 return std::pair<ProgramStateRef, ProgramStateRef>{State,
nullptr};
2725 return std::pair<ProgramStateRef, ProgramStateRef>{
nullptr, State};
2729 if (
X.isUnknownOrUndef()) {
2731 if (
const auto *Ex = dyn_cast<Expr>(
Condition)) {
2732 if (Ex->getType()->isIntegralOrEnumerationType()) {
2739 N->
getState()->getStateManager().getContext());
2749 if (
X.isUnknownOrUndef())
2750 return std::nullopt;
2755 return State->assume(
V);
2765 "CXXBindTemporaryExprs are handled by processBindTemporary.");
2768 currBldrCtx = &BldCtx;
2778 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2784 "Error evaluating branch");
2790 if (CheckersOutSet.
empty())
2795 if (PredN->isSink())
2802 std::tie(StTrue, StFalse) = *KnownCondValueAssumption;
2804 assert(!isa<ObjCForCollectionStmt>(
Condition));
2809 if (StTrue && StFalse)
2810 assert(!isa<ObjCForCollectionStmt>(
Condition));
2828 currBldrCtx =
nullptr;
2834 llvm::ImmutableSet<const VarDecl *>)
2843 currBldrCtx = &BuilderCtx;
2847 bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
2851 state = state->add<InitializedGlobalsSet>(VD);
2854 builder.generateNode(state, initHasRun, Pred);
2855 builder.markInfeasible(!initHasRun);
2857 currBldrCtx =
nullptr;
2878 for (iterator Succ : builder) {
2879 if (Succ.getLabel() == L) {
2880 builder.generateNode(Succ, state);
2885 llvm_unreachable(
"No block with label.");
2888 if (isa<UndefinedVal, loc::ConcreteInt>(
V)) {
2899 for (iterator Succ : builder)
2919 State = finishArgumentConstruction(
2934 while (LC != ToLC) {
2935 assert(LC &&
"ToLC must be a parent of FromLC!");
2936 for (
auto I : State->get<ObjectsUnderConstruction>())
2937 if (I.first.getLocationContext() == LC) {
2941 assert(I.first.getItem().getKind() ==
2943 I.first.getItem().getKind() ==
2945 State = State->remove<ObjectsUnderConstruction>(I.first);
2963 assert(areAllObjectsFullyConstructed(Pred->
getState(),
2976 for (
const auto I : AfterRemovedDead)
2994 if (CondV_untested.
isUndef()) {
3005 iterator I = builder.
begin(), EI = builder.
end();
3006 bool defaultIsFeasible = I == EI;
3008 for ( ; I != EI; ++I) {
3013 const CaseStmt *Case = I.getCase();
3027 if (std::optional<NonLoc> NL = CondV.
getAs<
NonLoc>())
3028 std::tie(StateCase, DefaultSt) =
3029 DefaultSt->assumeInclusiveRange(*NL, V1, V2);
3031 StateCase = DefaultSt;
3039 defaultIsFeasible =
true;
3041 defaultIsFeasible =
false;
3046 if (!defaultIsFeasible)
3078 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
3081 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
3084 const auto *MD = dyn_cast_or_null<CXXMethodDecl>(
D);
3085 const auto *DeclRefEx = dyn_cast<DeclRefExpr>(Ex);
3086 std::optional<std::pair<SVal, QualType>> VInfo;
3088 if (AMgr.
options.ShouldInlineLambdas && DeclRefEx &&
3089 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
3090 MD->getParent()->isLambda()) {
3093 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
3099 if (
const FieldDecl *FD = LambdaCaptureFields[VD]) {
3103 VInfo = std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
3108 VInfo = std::make_pair(state->getLValue(VD, LocCtxt), VD->getType());
3110 SVal V = VInfo->first;
3111 bool IsReference = VInfo->second->isReferenceType();
3117 V = state->getSVal(R);
3122 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3126 if (
const auto *ED = dyn_cast<EnumConstantDecl>(
D)) {
3132 if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
3134 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3138 if (isa<FieldDecl, IndirectFieldDecl>(
D)) {
3143 if (
const auto *BD = dyn_cast<BindingDecl>(
D)) {
3144 const auto *DD = cast<DecompositionDecl>(BD->getDecomposedDecl());
3146 SVal Base = state->getLValue(DD, LCtx);
3147 if (DD->getType()->isReferenceType()) {
3149 Base = state->getSVal(R);
3157 if (
const auto *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
3158 const auto *Field = cast<FieldDecl>(ME->getMemberDecl());
3159 V = state->getLValue(Field,
Base);
3162 else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BD->getBinding())) {
3163 SVal Idx = state->getSVal(ASE->getIdx(), LCtx);
3168 assert(Idx.
isConstant() &&
"BindingDecl array index is not a constant!");
3170 V = state->getLValue(BD->getType(), Idx,
Base);
3173 else if (
const auto *HV = BD->getHoldingVar()) {
3174 V = state->getLValue(HV, LCtx);
3176 if (HV->getType()->isReferenceType()) {
3178 V = state->getSVal(R);
3183 llvm_unreachable(
"An unknown case of structured binding encountered!");
3187 if (BD->getType()->isReferenceType() && !BD->getHoldingVar()) {
3189 V = state->getSVal(R);
3194 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3200 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
3206 llvm_unreachable(
"Support for this Decl not implemented.");
3221 for (
auto *
Node : CheckerPreStmt) {
3266 if (
const auto *ME = dyn_cast<MemberExpr>(Arr)) {
3267 Expr *MEBase = ME->getBase();
3270 if (
auto CXXSCE = dyn_cast<CXXStaticCastExpr>(MEBase)) {
3271 MEBase = CXXSCE->getSubExpr();
3274 auto ObjDeclExpr = cast<DeclRefExpr>(MEBase);
3275 SVal Obj = state->getLValue(cast<VarDecl>(ObjDeclExpr->getDecl()), LCtx);
3277 Base = state->getLValue(cast<FieldDecl>(ME->getMemberDecl()), Obj);
3292 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arr))
3293 Base = state->getLValue(cast<VarDecl>(DRE->getDecl()), LCtx);
3297 Base = state->getSVal(R);
3328 for (
auto *
Node : CheckerPreStmt) {
3332 if (IsGLValueLike) {
3341 SVal V = state->getLValue(
T,
3342 state->getSVal(Idx, LCtx),
3343 state->getSVal(
Base, LCtx));
3346 }
else if (IsVectorType) {
3350 llvm_unreachable(
"Array subscript should be an lValue when not \
3351a vector and not a forbidden lvalue type");
3370 if (isa<VarDecl, EnumConstantDecl>(
Member)) {
3371 for (
const auto I : CheckedSet)
3377 for (
const auto I : CheckedSet) {
3383 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member)) {
3384 if (MD->isImplicitObjectMemberFunction())
3385 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
3388 state = state->BindExpr(M, LCtx, MDVal);
3396 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr,
3403 if (
const auto *SR =
3404 dyn_cast_or_null<SymbolicRegion>(baseExprVal.
getAsRegion())) {
3405 QualType T = SR->getPointeeStaticType();
3410 const auto *field = cast<FieldDecl>(
Member);
3411 SVal L = state->getLValue(field, baseExprVal);
3421 dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
3422 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
3423 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
3427 if (field->getType()->isReferenceType()) {
3429 L = state->getSVal(R);
3434 Bldr.
generateNode(M, I, state->BindExpr(M, LCtx, L),
nullptr,
3458 for (
const auto I : AfterPreSet) {
3463 for (
unsigned SI = 0, Count = AE->
getNumSubExprs(); SI != Count; SI++) {
3465 SVal SubExprVal = State->getSVal(SubExpr, LCtx);
3466 ValuesToInvalidate.push_back(SubExprVal);
3469 State = State->invalidateRegions(ValuesToInvalidate, AE,
3476 State = State->BindExpr(AE, LCtx, ResultVal);
3496 for (
const std::pair<SVal, SVal> &LocAndVal : LocAndVals) {
3498 const MemRegion *MR = LocAndVal.first.getAsRegion();
3500 !isa<StackSpaceRegion, StaticGlobalSpaceRegion>(MR->
getMemorySpace())) {
3501 Escaped.push_back(LocAndVal.second);
3506 if (
const auto *VR = dyn_cast<VarRegion>(MR->
getBaseRegion()))
3507 if (VR->hasStackParametersStorage() && VR->getStackFrame()->inTopFrame())
3508 if (
const auto *RD = VR->getValueType()->getAsCXXRecordDecl())
3509 if (!RD->hasTrivialDestructor()) {
3510 Escaped.push_back(LocAndVal.second);
3519 SVal StoredVal = State->getSVal(MR);
3520 if (StoredVal != LocAndVal.second)
3523 Escaped.push_back(LocAndVal.second);
3526 if (Escaped.empty())
3529 return escapeValues(State, Escaped, Kind,
Call);
3535 std::pair<SVal, SVal> LocAndVal(
Loc, Val);
3546 if (!Invalidated || Invalidated->empty())
3559 for (
const auto I : ExplicitRegions) {
3561 SymbolsDirectlyInvalidated.insert(R->getSymbol());
3565 for (
const auto &sym : *Invalidated) {
3566 if (SymbolsDirectlyInvalidated.count(sym))
3568 SymbolsIndirectlyInvalidated.insert(sym);
3571 if (!SymbolsDirectlyInvalidated.empty())
3576 if (!SymbolsIndirectlyInvalidated.empty())
3597 StoreE, *
this, *PP);
3603 if (!isa<Loc>(location)) {
3608 Bldr.generateNode(L, state, Pred);
3612 for (
const auto PredI : CheckedSet) {
3620 state = state->bindLoc(location.
castAs<
Loc>(),
3621 Val, LC, !atDeclInit);
3624 if (std::optional<loc::MemRegionVal> LocRegVal =
3626 LocReg = LocRegVal->getRegion();
3630 Bldr.generateNode(L, state, PredI);
3643 const Expr *LocationE,
3649 const Expr *StoreE = AssignE ? AssignE : LocationE;
3653 evalLocation(Tmp, AssignE, LocationE, Pred, state, location,
false);
3661 for (
const auto I : Tmp)
3662 evalBind(Dst, StoreE, I, location, Val,
false);
3667 const Expr *BoundEx,
3673 assert(!isa<NonLoc>(location) &&
"location cannot be a NonLoc.");
3678 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location,
true);
3687 for (
const auto I : Tmp) {
3688 state = I->getState();
3695 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
3698 Bldr.
generateNode(NodeEx, I, state->BindExpr(BoundEx, LCtx,
V), tag,
3705 const Stmt *BoundEx,
3717 BldrTop.takeNodes(Pred);
3730 Bldr.generateNode(NodeEx, Pred, state, &tag);
3734 NodeEx, BoundEx, *
this);
3735 BldrTop.addNodes(Tmp);
3738std::pair<const ProgramPointTag *, const ProgramPointTag*>
3741 eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
3742 "Eagerly Assume True"),
3743 eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
3744 "Eagerly Assume False");
3745 return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
3746 &eagerlyAssumeBinOpBifurcationFalse);
3754 for (
const auto Pred : Src) {
3766 if (SEV && SEV->isExpression()) {
3767 const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
3771 std::tie(StateTrue, StateFalse) = state->assume(*SEV);
3804 assert(!isa<NonLoc>(
X));
3806 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3814 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3839 N->
getState()->getStateManager().getOwningEngine()).getBugReporter();
3842 for (
const auto &Report :
Class.getReports()) {
3843 const auto *PR = dyn_cast<PathSensitiveBugReport>(Report.get());
3861 llvm::function_ref<
void(
const ExplodedNode *)> PreCallback,
3862 llvm::function_ref<
void(
const ExplodedNode *)> PostCallback,
3884 llvm::raw_string_ostream Out(Buf);
3886 const bool IsDot =
true;
3887 const unsigned int Space = 1;
3890 Out <<
"{ \"state_id\": " << State->getID()
3893 Indent(Out, Space, IsDot) <<
"\"program_points\": [\\l";
3896 traverseHiddenNodes(
3899 Indent(Out, Space + 1, IsDot) <<
"{ ";
3901 Out <<
", \"tag\": ";
3903 Out <<
'\"' << Tag->getTagDescription() <<
'\"';
3906 Out <<
", \"node_id\": " << OtherNode->
getID() <<
3907 ", \"is_sink\": " << OtherNode->
isSink() <<
3908 ", \"has_report\": " << nodeHasBugReport(OtherNode) <<
" }";
3915 Indent(Out, Space, IsDot) <<
"],\\l";
3928 llvm::DisplayGraph(
Filename,
false, llvm::GraphProgram::DOT);
3933 llvm::DisplayGraph(
Filename,
false, llvm::GraphProgram::DOT);
3938 std::vector<const ExplodedNode *> Src;
3943 dyn_cast<PathSensitiveBugReport>(
Class.getReports()[0].get());
3946 const auto *N =
const_cast<ExplodedNode *
>(R->getErrorNode());
3952 return llvm::WriteGraph(&G,
"ExprEngine",
false,
3959 std::unique_ptr<ExplodedGraph> TrimmedG(G.
trim(
Nodes));
3961 if (!TrimmedG.get()) {
3962 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
3966 return llvm::WriteGraph(TrimmedG.get(),
"TrimmedExprEngine",
3968 "Trimmed Exploded Graph",
3973 static int index = 0;
3977void ExprEngine::anchor() { }
Defines the clang::ASTContext interface.
BoundNodesTreeBuilder Nodes
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....
Defines the clang::Expr interface and subclasses for C++ expressions.
static const Stmt * getRightmostLeaf(const Stmt *Condition)
std::pair< const ObjCForCollectionStmt *, const LocationContext * > ObjCForLctxPair
static SVal RecoverCastedSymbol(ProgramStateRef state, const Stmt *Condition, const LocationContext *LCtx, ASTContext &Ctx)
RecoverCastedSymbol - A helper function for ProcessBranch that is used to try to recover some path-se...
static void printObjectsUnderConstructionJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const LocationContext *LCtx, unsigned int Space=0, bool IsDot=false)
static void printIndicesOfElementsToConstructJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const LocationContext *LCtx, unsigned int Space=0, bool IsDot=false)
static void printStateTraitWithLocationContextJson(raw_ostream &Out, ProgramStateRef State, const LocationContext *LCtx, 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 printPendingArrayDestructionsJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const LocationContext *LCtx, unsigned int Space=0, bool IsDot=false)
static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S, const ExplodedNode *Pred, const LocationContext *LC)
static const Stmt * ResolveCondition(const Stmt *Condition, const CFGBlock *B)
REGISTER_TRAIT_WITH_PROGRAMSTATE(ObjectsUnderConstruction, ObjectsUnderConstructionMap) typedef llvm REGISTER_TRAIT_WITH_PROGRAMSTATE(IndexOfElementToConstruct, IndexOfElementToConstructMap) typedef llvm typedef llvm::ImmutableMap< const LocationContext *, unsigned > PendingArrayDestructionMap
static void printPendingInitLoopJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const LocationContext *LCtx, unsigned int Space=0, bool IsDot=false)
llvm::ImmutableMap< ConstructedObjectKey, SVal > ObjectsUnderConstructionMap
static std::optional< std::pair< ProgramStateRef, ProgramStateRef > > assumeCondition(const Stmt *Condition, ExplodedNode *N)
Split the state on whether there are any more iterations left for this loop.
STATISTIC(NumRemoveDeadBindings, "The # of times RemoveDeadBindings is called")
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
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 the SourceManager interface.
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 ...
SourceManager & getSourceManager()
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
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.
unsigned NoRetryExhausted
Do not re-analyze paths leading to exhausted nodes with a different strategy.
unsigned maxBlockVisitOnPath
The maximum number of times the analyzer visits a block.
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.
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.
Represents a single basic block in a source-level CFG.
CFGTerminator getTerminator() const
Stmt * getTerminatorStmt()
Represents C++ object destructor generated from a call to delete.
const CXXDeleteExpr * getDeleteExpr() const
Represents a top-level expression in a basic block.
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.
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.
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...
bool isStmtBranch() const
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
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 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.
SourceLocation getBeginLoc() const LLVM_READONLY
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
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, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
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.
Represents the declaration of a label.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const LocationContext * getParent() const
It might return null.
const StackFrameContext * getStackFrame() const
virtual bool inTopFrame() const
void printJson(raw_ostream &Out, const char *NL="\n", unsigned int Space=0, bool IsDot=false, std::function< void(const LocationContext *)> printMoreInfoPerContext=[](const LocationContext *) {}) const
Prints out the call stack in json format.
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.
void printJson(llvm::raw_ostream &Out, const char *NL="\n") const
@ PreStmtPurgeDeadSymbolsKind
@ PostStmtPurgeDeadSymbolsKind
const StackFrameContext * getStackFrame() const
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
const LocationContext * getLocationContext() const
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.
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
bool isCForbiddenLValueType() const
Determine whether expressions of the given type are forbidden from being lvalues in C.
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 (based on CallEvent).
unsigned getIndex() const
const Stmt * getCallSite() const
const CFGBlock * getCallSiteBlock() const
bool inTopFrame() const override
const Stmt * getStmt() const
Stmt - This represents one statement.
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.
bool isAllEnumCasesCovered() const
Returns true if the SwitchStmt is a switch of an enum value and all cases have been explicitly covere...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isReferenceType() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isVectorType() const
const T * getAs() const
Member-template getAs<specific type>'.
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.
const LangOptions & getLangOpts() const
ASTContext & getASTContext() override
AnalyzerOptions & options
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
void markInfeasible(bool branch)
ExplodedNode * generateNode(ProgramStateRef State, bool branch, ExplodedNode *Pred)
bool isFeasible(bool branch)
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.
void runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, ExprEngine &Eng, const ProgramPoint &PP)
Run checkers for binding of a value to a location.
void runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS)
Run checkers on end of function.
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 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.
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call)
Run checkers for region changes.
void 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 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 addAbortedBlock(const ExplodedNode *node, const CFGBlock *block)
Inform the CoreEngine that a basic block was aborted because it could not be completely analyzed.
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
void enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS)
enqueue the nodes corresponding to the end of function onto the end of path / work list.
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
std::unique_ptr< ExplodedGraph > trim(ArrayRef< const NodeTy * > Nodes, InterExplodedGraphMap *ForwardMap=nullptr, InterExplodedGraphMap *InverseMap=nullptr) const
Creates a trimmed version of the graph that only contains paths leading to the given nodes.
void enableNodeReclamation(unsigned Interval)
Enable tracking of recently allocated nodes for potential reclamation when calling reclaimRecentlyAll...
void reclaimRecentlyAllocatedNodes()
Reclaim "uninteresting" nodes created since the last time this method was called.
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 ...
roots_iterator roots_begin()
void insert(const ExplodedNodeSet &S)
void Add(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()
const StackFrameContext * getStackFrame() const
const LocationContext * getLocationContext() const
unsigned succ_size() const
void processEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, const ReturnStmt *RS=nullptr)
Called by CoreEngine.
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
ProgramStateManager & getStateManager()
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 VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L)
Called by CoreEngine.
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const LocationContext *LC, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer's garbage collection - remove dead symbols and bindings from the state.
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)
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)
ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion *MR, const LocationContext *LCtx)
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.
ProgramStateRef getInitialState(const LocationContext *InitLoc)
getInitialState - Return the initial state used for the root vertex in the ExplodedGraph.
void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr *DR, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for computing the lvalue of an Objective-C ivar.
static bool hasMoreIteration(ProgramStateRef State, const ObjCForCollectionStmt *O, const LocationContext *LC)
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.
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const LocationContext *LC)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
std::string DumpGraph(bool trim=false, StringRef Filename="")
Dump graph to the specified filename.
void printJson(raw_ostream &Out, ProgramStateRef State, const LocationContext *LCtx, const char *NL, unsigned int Space, bool IsDot) const
printJson - Called by ProgramStateManager to print checker-specific data.
InliningModes
The modes of inlining, which override the default analysis-wide settings.
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, ArrayRef< std::pair< SVal, SVal > > LocAndVals, const LocationContext *LCtx, PointerEscapeKind Kind, const CallEvent *Call)
Call PointerEscape callback when a value escapes as a result of bind.
const LocationContext * getRootLocationContext() const
static ProgramStateRef removeIterationState(ProgramStateRef State, const ObjCForCollectionStmt *O, const LocationContext *LC)
ProgramStateRef processAssume(ProgramStateRef state, SVal cond, bool assumption)
evalAssume - Callback function invoked by the ConstraintManager when making assumptions about state v...
static std::optional< unsigned > getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives which element is being constructed in a non-POD type array.
void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBlockExpr - Transfer function logic for BlockExprs.
void ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
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.
CFGBlock::ConstCFGElementRef getCFGElementRef() const
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
void processCFGBlockEntrance(const BlockEdge &L, NodeBuilderWithSinks &nodeBuilder, ExplodedNode *Pred)
Called by CoreEngine when processing the entrance of a CFGBlock.
void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void processBranch(const Stmt *Condition, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
ProcessBranch - Called by CoreEngine.
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call)
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store.
void ProcessStmt(const Stmt *S, ExplodedNode *Pred)
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.
static std::optional< unsigned > getPendingArrayDestruction(ProgramStateRef State, const LocationContext *LCtx)
Retreives which element is being destructed in a non-POD type array.
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.
void processCFGElement(const CFGElement E, ExplodedNode *Pred, unsigned StmtIdx, NodeBuilderContext *Ctx)
processCFGElement - Called by CoreEngine.
void processStaticInitializer(const DeclStmt *DS, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
Called by CoreEngine.
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
void ProcessLoopExit(const Stmt *S, ExplodedNode *Pred)
void processSwitch(SwitchNodeBuilder &builder)
ProcessSwitch - Called by CoreEngine.
void processEndWorklist()
Called by CoreEngine when the analysis worklist has terminated.
CheckerManager & getCheckerManager() const
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAtomicExpr - Transfer function for builtin atomic expressions.
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 VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
ConstraintManager & getConstraintManager()
void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, NodeBuilderContext &BldCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
Called by CoreEngine.
void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex)
evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic expressions of ...
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 removeDeadOnEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
static std::pair< const ProgramPointTag *, const ProgramPointTag * > geteagerlyAssumeBinOpBifurcationTags()
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
AnalysisManager & getAnalysisManager()
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 VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, ExplodedNodeSet &PreVisit, ExplodedNodeSet &Dst)
void processIndirectGoto(IndirectGotoNodeBuilder &builder)
processIndirectGoto - Called by CoreEngine.
const NodeBuilderContext & getBuilderContext()
static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives the size of the array in the pending ArrayInitLoopExpr.
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
void markReachedMaxBlockCount(const Decl *D)
const Expr * getTarget() const
const LocationContext * getLocationContext() const
ProgramStateRef getState() const
ExplodedNode * generateNode(const iterator &I, ProgramStateRef State, bool isSink=false)
static bool isLocType(QualType T)
const CXXLifetimeExtendedObjectRegion * getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD, LocationContext const *LC)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by local referen...
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
const CXXLifetimeExtendedObjectRegion * getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by static refere...
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
This node builder keeps track of the generated sink nodes.
ExplodedNode * generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
This is the simplest builder which generates nodes in the ExplodedGraph.
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
void takeNodes(const ExplodedNodeSet &S)
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
void addNodes(const ExplodedNodeSet &S)
const NodeBuilderContext & getContext()
While alive, includes the current analysis stack in a crash trace.
ProgramStateRef removeDeadBindingsFromEnvironmentAndStore(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) const
bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) const
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
MemRegionManager & getRegionManager()
ProgramStateRef getInitialState(const LocationContext *InitLoc)
StoreManager & getStoreManager()
Information about invalidation for a particular region/symbol.
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
DefinedSVal getFunctionPointer(const FunctionDecl *func)
NonLoc makeIntValWithWidth(QualType ptrType, uint64_t integer)
NonLoc makeArrayIndex(uint64_t idx)
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
QualType getConditionType() const
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
std::optional< SVal > getConstantVal(const Expr *E)
Returns the value of E, if it can be determined in a non-path-sensitive manner.
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 llvm::APSInt * getAsInteger() const
If this SVal is loc::ConcreteInt or nonloc::ConcreteInt, return a pointer to APSInt which is held in ...
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
This builder class is useful for generating nodes that resulted from visiting a statement.
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
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.
ProgramStateRef getState() const
const Expr * getCondition() const
ExplodedNode * generateDefaultCaseNode(ProgramStateRef State, bool isSink=false)
ExplodedNode * generateCaseStmtNode(const iterator &I, ProgramStateRef State)
const LocationContext * getLocationContext() const
const SwitchStmt * getSwitch() const
A class responsible for cleaning up unused symbols.
void markLive(SymbolRef sym)
Unconditionally marks a symbol as live.
SymbolicRegion - A special, "non-concrete" region.
TypedValueRegion - An abstract class representing regions having a typed value.
Represents symbolic expression that isn't a location.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
llvm::DenseSet< const Decl * > SetOfConstDecls
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)
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State)
Updates the given ProgramState.
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState, const LocationContext *LCtx, unsigned BlockCount, const Stmt *LoopStmt)
Get the states that result from widening the loop.
llvm::DenseSet< SymbolRef > InvalidatedSymbols
bool isUnrolledState(ProgramStateRef State)
Returns if the given State indicates that is inside a completely unrolled loop.
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 operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
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
@ 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.
An adjustment to be made to the temporary created when emitting a reference binding,...
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
Hints for figuring out of 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)