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 LocationContext *>;
127 const ConstructedObjectKeyImpl Impl;
134 const ConstructionContextItem &getItem()
const {
return Impl.first; }
135 const LocationContext *getLocationContext()
const {
return Impl.second; }
137 ASTContext &getASTContext()
const {
138 return getLocationContext()->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 LocationContext *>,
unsigned>
200 IndexOfElementToConstructMap;
202 IndexOfElementToConstructMap)
207typedef llvm::ImmutableMap<
208 std::pair<const CXXConstructExpr *, const LocationContext *>,
unsigned>
212typedef llvm::ImmutableMap<const LocationContext *, 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, InitLoc);
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, InitLoc);
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, LC);
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, LC);
390 State = State->BindExpr(
Result, LC, *
V);
392 }
else if (
const ValueDecl *VD = MT->getExtendingDecl()) {
398 TR = MRMgr.getCXXStaticLifetimeExtendedObjectRegion(
Init, VD);
400 TR = MRMgr.getCXXLifetimeExtendedObjectRegion(
Init, VD, LC);
404 TR = MRMgr.getCXXTempObjectRegion(
Init, LC);
407 TR = MRMgr.getCXXTempObjectRegion(
Init, LC);
410 SVal Reg = loc::MemRegionVal(TR);
414 for (
const SubobjectAdjustment &Adj : llvm::reverse(Adjustments)) {
426 nullptr,
nullptr,
nullptr);
439 SVal InitVal = State->getSVal(
Init, LC);
443 State = State->bindLoc(BaseReg.
castAs<Loc>(), InitVal, LC,
false);
447 if (InitValWithAdjustments.
isUnknown()) {
455 State->bindLoc(Reg.
castAs<Loc>(), InitValWithAdjustments, LC,
false);
457 State = State->bindLoc(BaseReg.
castAs<Loc>(), InitVal, LC,
false);
463 if (
Result->isGLValue()) {
464 State = State->BindExpr(
Result, LC, Reg);
466 State = State->BindExpr(
Result, LC, InitValWithAdjustments);
472 if (OutRegionWithAdjustments)
479 const LocationContext *LCtx,
unsigned Idx) {
482 assert(!State->contains<IndexOfElementToConstruct>(Key) || Idx > 0);
484 return State->set<IndexOfElementToConstruct>(Key, Idx);
487std::optional<unsigned>
490 const unsigned *
V = State->get<PendingInitLoop>({E, LCtx->
getStackFrame()});
491 return V ? std::make_optional(*
V) : std::nullopt;
499 assert(E && State->contains<PendingInitLoop>(Key));
500 return State->remove<PendingInitLoop>(Key);
509 assert(!State->contains<PendingInitLoop>(Key) && Size > 0);
511 return State->set<PendingInitLoop>(Key, Size);
514std::optional<unsigned>
519 State->get<IndexOfElementToConstruct>({E, LCtx->
getStackFrame()});
520 return V ? std::make_optional(*
V) : std::nullopt;
529 assert(E && State->contains<IndexOfElementToConstruct>(Key));
530 return State->remove<IndexOfElementToConstruct>(Key);
533std::optional<unsigned>
536 assert(LCtx &&
"LocationContext shouldn't be null!");
540 return V ? std::make_optional(*
V) : std::nullopt;
545 assert(LCtx &&
"LocationContext shouldn't be null!");
549 return State->set<PendingArrayDestruction>(Key, Idx);
555 assert(LCtx &&
"LocationContext shouldn't be null!");
559 assert(LCtx && State->contains<PendingArrayDestruction>(Key));
560 return State->remove<PendingArrayDestruction>(Key);
571 if (
auto DS = dyn_cast_or_null<DeclStmt>(Item.
getStmtOrNull())) {
572 if (
auto VD = dyn_cast_or_null<VarDecl>(DS->getSingleDecl()))
573 Init = VD->getInit();
576 if (
auto LE = dyn_cast_or_null<LambdaExpr>(Item.
getStmtOrNull()))
585 if (
const auto *AILE = dyn_cast_or_null<ArrayInitLoopExpr>(
Init))
594 assert((!State->get<ObjectsUnderConstruction>(Key) ||
595 Key.getItem().getKind() ==
597 State->contains<IndexOfElementToConstruct>(
598 {dyn_cast_or_null<CXXConstructExpr>(Init), LC})) &&
599 "The object is already marked as `UnderConstruction`, when it's not "
601 return State->set<ObjectsUnderConstruction>(Key,
V);
609 const SVal *
V = State->get<ObjectsUnderConstruction>(Key);
610 return V ? std::make_optional(*
V) : std::nullopt;
618 assert(State->contains<ObjectsUnderConstruction>(Key));
619 return State->remove<ObjectsUnderConstruction>(Key);
625 ConstructedObjectKey Key({BTE,
true}, LC);
628 return State->set<ObjectsUnderConstruction>(Key,
UnknownVal());
633 const CXXBindTemporaryExpr *BTE,
634 const LocationContext *LC) {
635 ConstructedObjectKey Key({BTE,
true}, LC);
636 assert(State->contains<ObjectsUnderConstruction>(Key));
637 return State->remove<ObjectsUnderConstruction>(Key);
641 const CXXBindTemporaryExpr *BTE,
642 const LocationContext *LC) {
643 ConstructedObjectKey Key({BTE,
true}, LC);
644 return State->contains<ObjectsUnderConstruction>(Key);
648 const LocationContext *FromLC,
649 const LocationContext *ToLC) {
650 const LocationContext *LC = FromLC;
652 assert(LC &&
"ToLC must be a parent of FromLC!");
653 for (
auto I : State->get<ObjectsUnderConstruction>())
654 if (I.first.getLocationContext() == LC)
670 SVal cond,
bool assumption) {
689 unsigned int Space = 0,
bool IsDot =
false) {
694 bool HasItem =
false;
697 const ConstructedObjectKey *LastKey =
nullptr;
698 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
699 const ConstructedObjectKey &Key = I.first;
700 if (Key.getLocationContext() != LCtx)
711 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
712 const ConstructedObjectKey &Key = I.first;
714 if (Key.getLocationContext() != LCtx)
717 Indent(Out, Space, IsDot) <<
"{ ";
718 Key.printJson(Out,
nullptr, PP);
719 Out <<
", \"value\": \"" <<
Value <<
"\" }";
727 Indent(Out, --Space, IsDot) <<
']';
735 const LocationContext *LCtx,
unsigned int Space = 0,
bool IsDot =
false) {
736 using KeyT = std::pair<const Expr *, const LocationContext *>;
742 bool HasItem =
false;
746 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
747 const KeyT &Key = I.first;
748 if (Key.second != LCtx)
759 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
760 const KeyT &Key = I.first;
761 unsigned Value = I.second;
762 if (Key.second != LCtx)
765 Indent(Out, Space, IsDot) <<
"{ ";
768 const Expr *E = Key.first;
769 Out <<
"\"stmt_id\": " << E->
getID(Context);
772 Out <<
", \"kind\": null";
775 Out <<
", \"pretty\": ";
781 Out <<
", \"value\": \"Current index: " <<
Value - 1 <<
"\" }";
789 Indent(Out, --Space, IsDot) <<
']';
798 unsigned int Space = 0,
799 bool IsDot =
false) {
800 using KeyT = std::pair<const CXXConstructExpr *, const LocationContext *>;
806 bool HasItem =
false;
810 for (
const auto &I : State->get<PendingInitLoop>()) {
811 const KeyT &Key = I.first;
812 if (Key.second != LCtx)
823 for (
const auto &I : State->get<PendingInitLoop>()) {
824 const KeyT &Key = I.first;
825 unsigned Value = I.second;
826 if (Key.second != LCtx)
829 Indent(Out, Space, IsDot) <<
"{ ";
832 Out <<
"\"stmt_id\": " << E->
getID(Context);
834 Out <<
", \"kind\": null";
835 Out <<
", \"pretty\": ";
841 Out <<
", \"value\": \"Flattened size: " <<
Value <<
"\"}";
849 Indent(Out, --Space, IsDot) <<
']';
858 unsigned int Space = 0,
bool IsDot =
false) {
862 bool HasItem =
false;
865 KeyT LastKey =
nullptr;
866 for (
const auto &I : State->get<PendingArrayDestruction>()) {
867 const KeyT &Key = I.first;
879 for (
const auto &I : State->get<PendingArrayDestruction>()) {
880 const KeyT &Key = I.first;
884 Indent(Out, Space, IsDot) <<
"{ ";
886 Out <<
"\"stmt_id\": null";
887 Out <<
", \"kind\": null";
888 Out <<
", \"pretty\": \"Current index: \"";
889 Out <<
", \"value\": \"" << I.second <<
"\" }";
897 Indent(Out, --Space, IsDot) <<
']';
911template <
typename Trait,
typename Printer,
typename... Args>
914 const char *NL,
unsigned int Space,
bool IsDot,
915 const char *jsonPropertyName, Printer printer, Args &&...args) {
923 static_assert(std::is_function_v<std::remove_pointer_t<Printer>>,
924 "Printer is not a function!");
925 static_assert(std::is_convertible_v<Printer, RequiredType>,
926 "Printer doesn't have the required type!");
928 if (LCtx && !State->get<Trait>().isEmpty()) {
929 Indent(Out, Space, IsDot) <<
'\"' << jsonPropertyName <<
"\": ";
933 printer(Out, State, NL, LC, Space, IsDot, std::forward<Args>(args)...);
937 Indent(Out, Space, IsDot) <<
"]," << NL;
943 unsigned int Space,
bool IsDot)
const {
946 Out, State, LCtx, NL, Space, IsDot,
"constructing_objects",
949 Out, State, LCtx, NL, Space, IsDot,
"index_of_element",
952 Out, State, LCtx, NL, Space, IsDot,
"pending_init_loops",
955 Out, State, LCtx, NL, Space, IsDot,
"pending_destructors",
970 currStmtIdx = StmtIdx;
1031 const Stmt *ReferenceStmt,
1033 const Stmt *DiagnosticStmt,
1035 llvm::TimeTraceScope TimeScope(
"ExprEngine::removeDead");
1038 &&
"PostStmt is not generally supported by the SymbolReaper yet");
1039 assert(LC &&
"Must pass the current (or expiring) LocationContext");
1041 if (!DiagnosticStmt) {
1042 DiagnosticStmt = ReferenceStmt;
1043 assert(DiagnosticStmt &&
"Required for clearing a LocationContext");
1046 NumRemoveDeadBindings++;
1052 if (!ReferenceStmt) {
1054 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
1061 for (
auto I : CleanedState->get<ObjectsUnderConstruction>()) {
1062 if (
SymbolRef Sym = I.second.getAsSymbol())
1064 if (
const MemRegion *MR = I.second.getAsRegion())
1073 CleanedState = StateMgr.removeDeadBindingsFromEnvironmentAndStore(
1074 CleanedState, SFC, SymReaper);
1081 DiagnosticStmt, *
this, K);
1092 for (
const auto I : CheckedSet) {
1099 assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->
getState()) &&
1100 "Checkers are not allowed to modify the Environment as a part of "
1101 "checkDeadSymbols processing.");
1102 assert(StateMgr.haveEqualStores(CheckerState, Pred->
getState()) &&
1103 "Checkers are not allowed to modify the Store as a part of "
1104 "checkDeadSymbols processing.");
1109 StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
1121 G.reclaimRecentlyAllocatedNodes();
1125 "Error evaluating statement");
1134 CleanedStates.
insert(Pred);
1138 for (
const auto I : CleanedStates) {
1141 Visit(currStmt, I, DstI);
1146 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1152 "Error evaluating end of the loop");
1155 if(AMgr.options.ShouldUnrollLoops)
1161 Engine.enqueueStmtNode(N,
getCurrBlock(), currStmtIdx);
1172 "Error evaluating initializer");
1179 SVal thisVal = State->getSVal(svalBuilder.getCXXThis(
decl, stackFrame));
1191 State = finishObjectConstruction(State, BMI, LC);
1193 Tmp.
insert(Engine.makeNode(PS, State, Pred));
1201 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
1205 if (
Init->getType()->isArrayType()) {
1209 while ((ASE = dyn_cast<ArraySubscriptExpr>(
Init)))
1212 InitVal = State->getSVal(
Init, stackFrame);
1222 InitVal = State->getSVal(BMI->
getInit(), stackFrame);
1226 evalBind(Tmp,
Init, Pred, FieldLoc, InitVal,
true, &PP);
1234 SVal InitVal = State->getSVal(
Init, stackFrame);
1235 evalBind(Tmp,
Init, Pred, BaseLoc, InitVal,
true);
1250 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
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.");
1314 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1325 if (Opts.MayInlineCXXAllocator)
1333 Engine.enqueueStmtNodes(Dst,
getCurrBlock(), currStmtIdx);
1350 const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
1365 std::tie(state, Idx) = prepareStateForArrayDestruction(
1366 state, Region, varType, LCtx, &ElementCount);
1368 if (ElementCount.isConstant()) {
1369 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1370 assert(ArrayLength &&
1371 "An automatic dtor for a 0 length array shouldn't be triggered!");
1376 "ExprEngine",
"Skipping automatic 0 length array destruction, "
1377 "which shouldn't be in the CFG.");
1395 "Prepare for object destruction");
1405 false, Pred, Dst, CallOpts);
1416 SVal ArgVal = State->getSVal(Arg, LCtx);
1420 if (State->isNull(ArgVal).isConstrainedTrue()) {
1431 auto getDtorDecl = [](
const QualType &DTy) {
1443 while (
const auto *AT =
getContext().getAsArrayType(DTy))
1444 DTy = AT->getElementType();
1448 std::tie(State, Idx) = prepareStateForArrayDestruction(
1449 State, ArgR, DTy, LCtx, &ElementCount);
1453 if (ElementCount.isConstant() &&
1454 ElementCount.getAsInteger()->getLimitedValue() == 0) {
1457 "ExprEngine",
"Skipping 0 length array delete destruction");
1465 ArgR = State->getLValue(DTy, svalBuilder.makeArrayIndex(Idx), ArgVal)
1472 "Prepare for object destruction");
1501 true, Pred, Dst, CallOpts);
1513 Loc ThisStorageLoc =
1515 Loc ThisLoc = State->getSVal(ThisStorageLoc).
castAs<
Loc>();
1516 SVal FieldVal = State->getLValue(
Member, ThisLoc);
1521 std::tie(State, Idx) = prepareStateForArrayDestruction(
1522 State, FieldVal.getAsRegion(), T, LCtx, &ElementCount);
1524 if (ElementCount.isConstant()) {
1525 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1526 assert(ArrayLength &&
1527 "A member dtor for a 0 length array shouldn't be triggered!");
1532 "ExprEngine",
"Skipping member 0 length array destruction, which "
1533 "shouldn't be in the CFG.");
1550 "Prepare for object destruction");
1560 false, Pred, Dst, CallOpts);
1578 MR =
V->getAsRegion();
1583 if (isDestructorElided(State, BTE, LC)) {
1584 State = cleanupElidedDestructor(State, BTE, LC);
1594 NodeBuilder Builder(Pred, CleanDtorState, *currBldrCtx);
1600 assert(CleanDtorState.
size() <= 1);
1602 CleanDtorState.
empty() ? Pred : *CleanDtorState.
begin();
1625 T = AT->getElementType();
1636 false, CleanPred, Dst, CallOpts);
1675 State = addObjectUnderConstruction(State, BTE, LC,
UnknownVal());
1677 Builder.generateNode(BTE, Node, State);
1685 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
1690 : Symbols(Symbols) {}
1694 bool VisitSymbol(
SymbolRef Sym)
override {
1695 Symbols.insert(Sym);
1700 CollectReachableSymbolsCallback CallBack(Symbols);
1702 State->scanReachableSymbols(
V, CallBack);
1705 State, CallBack.getSymbols(),
Call, K,
nullptr);
1719 case Stmt::CXXDependentScopeMemberExprClass:
1720 case Stmt::CXXReflectExprClass:
1721 case Stmt::CXXTryStmtClass:
1722 case Stmt::CXXTypeidExprClass:
1723 case Stmt::CXXUuidofExprClass:
1724 case Stmt::CXXFoldExprClass:
1725 case Stmt::MSPropertyRefExprClass:
1726 case Stmt::MSPropertySubscriptExprClass:
1727 case Stmt::CXXUnresolvedConstructExprClass:
1728 case Stmt::DependentScopeDeclRefExprClass:
1729 case Stmt::ArrayTypeTraitExprClass:
1730 case Stmt::ExpressionTraitExprClass:
1731 case Stmt::UnresolvedLookupExprClass:
1732 case Stmt::UnresolvedMemberExprClass:
1733 case Stmt::RecoveryExprClass:
1734 case Stmt::CXXNoexceptExprClass:
1735 case Stmt::PackExpansionExprClass:
1736 case Stmt::PackIndexingExprClass:
1737 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1738 case Stmt::FunctionParmPackExprClass:
1739 case Stmt::CoroutineBodyStmtClass:
1740 case Stmt::CoawaitExprClass:
1741 case Stmt::DependentCoawaitExprClass:
1742 case Stmt::CoreturnStmtClass:
1743 case Stmt::CoyieldExprClass:
1744 case Stmt::SEHTryStmtClass:
1745 case Stmt::SEHExceptStmtClass:
1746 case Stmt::SEHLeaveStmtClass:
1747 case Stmt::SEHFinallyStmtClass:
1748 case Stmt::OMPCanonicalLoopClass:
1749 case Stmt::OMPParallelDirectiveClass:
1750 case Stmt::OMPSimdDirectiveClass:
1751 case Stmt::OMPForDirectiveClass:
1752 case Stmt::OMPForSimdDirectiveClass:
1753 case Stmt::OMPSectionsDirectiveClass:
1754 case Stmt::OMPSectionDirectiveClass:
1755 case Stmt::OMPScopeDirectiveClass:
1756 case Stmt::OMPSingleDirectiveClass:
1757 case Stmt::OMPMasterDirectiveClass:
1758 case Stmt::OMPCriticalDirectiveClass:
1759 case Stmt::OMPParallelForDirectiveClass:
1760 case Stmt::OMPParallelForSimdDirectiveClass:
1761 case Stmt::OMPParallelSectionsDirectiveClass:
1762 case Stmt::OMPParallelMasterDirectiveClass:
1763 case Stmt::OMPParallelMaskedDirectiveClass:
1764 case Stmt::OMPTaskDirectiveClass:
1765 case Stmt::OMPTaskyieldDirectiveClass:
1766 case Stmt::OMPBarrierDirectiveClass:
1767 case Stmt::OMPTaskwaitDirectiveClass:
1768 case Stmt::OMPErrorDirectiveClass:
1769 case Stmt::OMPTaskgroupDirectiveClass:
1770 case Stmt::OMPFlushDirectiveClass:
1771 case Stmt::OMPDepobjDirectiveClass:
1772 case Stmt::OMPScanDirectiveClass:
1773 case Stmt::OMPOrderedDirectiveClass:
1774 case Stmt::OMPAtomicDirectiveClass:
1775 case Stmt::OMPAssumeDirectiveClass:
1776 case Stmt::OMPTargetDirectiveClass:
1777 case Stmt::OMPTargetDataDirectiveClass:
1778 case Stmt::OMPTargetEnterDataDirectiveClass:
1779 case Stmt::OMPTargetExitDataDirectiveClass:
1780 case Stmt::OMPTargetParallelDirectiveClass:
1781 case Stmt::OMPTargetParallelForDirectiveClass:
1782 case Stmt::OMPTargetUpdateDirectiveClass:
1783 case Stmt::OMPTeamsDirectiveClass:
1784 case Stmt::OMPCancellationPointDirectiveClass:
1785 case Stmt::OMPCancelDirectiveClass:
1786 case Stmt::OMPTaskLoopDirectiveClass:
1787 case Stmt::OMPTaskLoopSimdDirectiveClass:
1788 case Stmt::OMPMasterTaskLoopDirectiveClass:
1789 case Stmt::OMPMaskedTaskLoopDirectiveClass:
1790 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
1791 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
1792 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
1793 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
1794 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1795 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
1796 case Stmt::OMPDistributeDirectiveClass:
1797 case Stmt::OMPDistributeParallelForDirectiveClass:
1798 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1799 case Stmt::OMPDistributeSimdDirectiveClass:
1800 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1801 case Stmt::OMPTargetSimdDirectiveClass:
1802 case Stmt::OMPTeamsDistributeDirectiveClass:
1803 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1804 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1805 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1806 case Stmt::OMPTargetTeamsDirectiveClass:
1807 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1808 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1809 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1810 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1811 case Stmt::OMPReverseDirectiveClass:
1812 case Stmt::OMPStripeDirectiveClass:
1813 case Stmt::OMPTileDirectiveClass:
1814 case Stmt::OMPInterchangeDirectiveClass:
1815 case Stmt::OMPSplitDirectiveClass:
1816 case Stmt::OMPFuseDirectiveClass:
1817 case Stmt::OMPInteropDirectiveClass:
1818 case Stmt::OMPDispatchDirectiveClass:
1819 case Stmt::OMPMaskedDirectiveClass:
1820 case Stmt::OMPGenericLoopDirectiveClass:
1821 case Stmt::OMPTeamsGenericLoopDirectiveClass:
1822 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
1823 case Stmt::OMPParallelGenericLoopDirectiveClass:
1824 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
1825 case Stmt::CapturedStmtClass:
1826 case Stmt::SYCLKernelCallStmtClass:
1827 case Stmt::UnresolvedSYCLKernelCallStmtClass:
1828 case Stmt::OpenACCComputeConstructClass:
1829 case Stmt::OpenACCLoopConstructClass:
1830 case Stmt::OpenACCCombinedConstructClass:
1831 case Stmt::OpenACCDataConstructClass:
1832 case Stmt::OpenACCEnterDataConstructClass:
1833 case Stmt::OpenACCExitDataConstructClass:
1834 case Stmt::OpenACCHostDataConstructClass:
1835 case Stmt::OpenACCWaitConstructClass:
1836 case Stmt::OpenACCCacheConstructClass:
1837 case Stmt::OpenACCInitConstructClass:
1838 case Stmt::OpenACCShutdownConstructClass:
1839 case Stmt::OpenACCSetConstructClass:
1840 case Stmt::OpenACCUpdateConstructClass:
1841 case Stmt::OpenACCAtomicConstructClass:
1842 case Stmt::OMPUnrollDirectiveClass:
1843 case Stmt::OMPMetaDirectiveClass:
1844 case Stmt::HLSLOutArgExprClass: {
1850 case Stmt::ParenExprClass:
1851 llvm_unreachable(
"ParenExprs already handled.");
1852 case Stmt::GenericSelectionExprClass:
1853 llvm_unreachable(
"GenericSelectionExprs already handled.");
1856 case Stmt::BreakStmtClass:
1857 case Stmt::CaseStmtClass:
1858 case Stmt::CompoundStmtClass:
1859 case Stmt::ContinueStmtClass:
1860 case Stmt::CXXForRangeStmtClass:
1861 case Stmt::DefaultStmtClass:
1862 case Stmt::DoStmtClass:
1863 case Stmt::ForStmtClass:
1864 case Stmt::GotoStmtClass:
1865 case Stmt::IfStmtClass:
1866 case Stmt::IndirectGotoStmtClass:
1867 case Stmt::LabelStmtClass:
1869 case Stmt::NullStmtClass:
1870 case Stmt::SwitchStmtClass:
1871 case Stmt::WhileStmtClass:
1872 case Stmt::DeferStmtClass:
1873 case Expr::MSDependentExistsStmtClass:
1874 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
1875 case Stmt::ImplicitValueInitExprClass:
1879 llvm_unreachable(
"Should be pruned from CFG");
1881 case Stmt::ObjCSubscriptRefExprClass:
1882 case Stmt::ObjCPropertyRefExprClass:
1883 llvm_unreachable(
"These are handled by PseudoObjectExpr");
1885 case Stmt::GNUNullExprClass: {
1888 state = state->BindExpr(
1890 svalBuilder.makeIntValWithWidth(
getContext().VoidPtrTy, 0));
1895 case Stmt::ObjCAtSynchronizedStmtClass:
1901 case Expr::ConstantExprClass:
1902 case Stmt::ExprWithCleanupsClass:
1906 case Stmt::CXXBindTemporaryExprClass: {
1917 case Stmt::ArrayInitLoopExprClass:
1923 case Stmt::DesignatedInitExprClass:
1924 case Stmt::DesignatedInitUpdateExprClass:
1925 case Stmt::ArrayInitIndexExprClass:
1926 case Stmt::ExtVectorElementExprClass:
1927 case Stmt::MatrixElementExprClass:
1928 case Stmt::ImaginaryLiteralClass:
1929 case Stmt::ObjCAtCatchStmtClass:
1930 case Stmt::ObjCAtFinallyStmtClass:
1931 case Stmt::ObjCAtTryStmtClass:
1932 case Stmt::ObjCAutoreleasePoolStmtClass:
1933 case Stmt::ObjCEncodeExprClass:
1934 case Stmt::ObjCIsaExprClass:
1935 case Stmt::ObjCProtocolExprClass:
1936 case Stmt::ObjCSelectorExprClass:
1937 case Stmt::ParenListExprClass:
1938 case Stmt::ShuffleVectorExprClass:
1939 case Stmt::ConvertVectorExprClass:
1940 case Stmt::VAArgExprClass:
1941 case Stmt::CUDAKernelCallExprClass:
1942 case Stmt::OpaqueValueExprClass:
1943 case Stmt::AsTypeExprClass:
1944 case Stmt::ConceptSpecializationExprClass:
1945 case Stmt::CXXRewrittenBinaryOperatorClass:
1946 case Stmt::RequiresExprClass:
1947 case Stmt::EmbedExprClass:
1952 case Stmt::PredefinedExprClass:
1953 case Stmt::AddrLabelExprClass:
1954 case Stmt::IntegerLiteralClass:
1955 case Stmt::FixedPointLiteralClass:
1956 case Stmt::CharacterLiteralClass:
1957 case Stmt::CXXScalarValueInitExprClass:
1958 case Stmt::CXXBoolLiteralExprClass:
1959 case Stmt::ObjCBoolLiteralExprClass:
1960 case Stmt::ObjCAvailabilityCheckExprClass:
1961 case Stmt::FloatingLiteralClass:
1962 case Stmt::NoInitExprClass:
1963 case Stmt::SizeOfPackExprClass:
1964 case Stmt::StringLiteralClass:
1965 case Stmt::SourceLocExprClass:
1966 case Stmt::ObjCStringLiteralClass:
1967 case Stmt::CXXPseudoDestructorExprClass:
1968 case Stmt::SubstNonTypeTemplateParmExprClass:
1969 case Stmt::CXXNullPtrLiteralExprClass:
1970 case Stmt::ArraySectionExprClass:
1971 case Stmt::OMPArrayShapingExprClass:
1972 case Stmt::OMPIteratorExprClass:
1973 case Stmt::SYCLUniqueStableNameExprClass:
1974 case Stmt::OpenACCAsteriskSizeExprClass:
1975 case Stmt::TypeTraitExprClass: {
1984 case Stmt::AttributedStmtClass: {
1991 case Stmt::CXXDefaultArgExprClass:
1992 case Stmt::CXXDefaultInitExprClass: {
2001 if (
const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
2002 ArgE = DefE->getExpr();
2003 else if (
const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
2004 ArgE = DefE->getExpr();
2006 llvm_unreachable(
"unknown constant wrapper kind");
2008 bool IsTemporary =
false;
2009 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
2010 ArgE = MTE->getSubExpr();
2014 std::optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
2019 for (
const auto I : PreVisit) {
2021 State = State->BindExpr(
cast<Expr>(S), LCtx, *ConstantVal);
2023 State = createTemporaryRegionIfNeeded(State, LCtx,
2035 case Stmt::CXXStdInitializerListExprClass:
2036 case Expr::ObjCArrayLiteralClass:
2037 case Expr::ObjCDictionaryLiteralClass:
2038 case Expr::ObjCBoxedExprClass: {
2048 QualType resultType = Ex->getType();
2050 for (
const auto N : preVisit) {
2052 SVal result = svalBuilder.conjureSymbolVal(
2062 for (
auto Child : Ex->children()) {
2064 SVal Val = State->getSVal(Child, LCtx);
2076 case Stmt::ArraySubscriptExprClass:
2082 case Stmt::MatrixSingleSubscriptExprClass:
2084 "Support for MatrixSingleSubscriptExprClass is not implemented.");
2087 case Stmt::MatrixSubscriptExprClass:
2088 llvm_unreachable(
"Support for MatrixSubscriptExpr is not implemented.");
2091 case Stmt::GCCAsmStmtClass: {
2103 case Stmt::MSAsmStmtClass:
2109 case Stmt::BlockExprClass:
2115 case Stmt::LambdaExprClass:
2116 if (AMgr.options.ShouldInlineLambdas) {
2126 case Stmt::BinaryOperatorClass: {
2128 if (B->isLogicalOp()) {
2134 else if (B->getOpcode() == BO_Comma) {
2138 state->getSVal(B->getRHS(),
2145 if (AMgr.options.ShouldEagerlyAssume &&
2146 (B->isRelationalOp() || B->isEqualityOp())) {
2158 case Stmt::CXXOperatorCallExprClass: {
2163 const Decl *Callee = OCE->getCalleeDecl();
2164 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
2165 if (MD->isImplicitObjectMemberFunction()) {
2169 createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
2170 if (NewState != State) {
2182 case Stmt::CallExprClass:
2183 case Stmt::CXXMemberCallExprClass:
2184 case Stmt::UserDefinedLiteralClass:
2190 case Stmt::CXXCatchStmtClass:
2196 case Stmt::CXXTemporaryObjectExprClass:
2197 case Stmt::CXXConstructExprClass:
2203 case Stmt::CXXInheritedCtorInitExprClass:
2210 case Stmt::CXXNewExprClass: {
2217 for (
const auto i : PreVisit)
2225 case Stmt::CXXDeleteExprClass: {
2233 for (
const auto i : PostVisit)
2242 case Stmt::ChooseExprClass: {
2250 case Stmt::CompoundAssignOperatorClass:
2256 case Stmt::CompoundLiteralExprClass:
2262 case Stmt::BinaryConditionalOperatorClass:
2263 case Stmt::ConditionalOperatorClass: {
2271 case Stmt::CXXThisExprClass:
2277 case Stmt::DeclRefExprClass: {
2285 case Stmt::DeclStmtClass:
2291 case Stmt::ImplicitCastExprClass:
2292 case Stmt::CStyleCastExprClass:
2293 case Stmt::CXXStaticCastExprClass:
2294 case Stmt::CXXDynamicCastExprClass:
2295 case Stmt::CXXReinterpretCastExprClass:
2296 case Stmt::CXXConstCastExprClass:
2297 case Stmt::CXXFunctionalCastExprClass:
2298 case Stmt::BuiltinBitCastExprClass:
2299 case Stmt::ObjCBridgedCastExprClass:
2300 case Stmt::CXXAddrspaceCastExprClass: {
2312 case Expr::MaterializeTemporaryExprClass: {
2318 for (
const auto i : dstPrevisit)
2325 case Stmt::InitListExprClass: {
2333 case Expr::CXXParenListInitExprClass: {
2342 case Stmt::MemberExprClass:
2348 case Stmt::AtomicExprClass:
2354 case Stmt::ObjCIvarRefExprClass:
2360 case Stmt::ObjCForCollectionStmtClass:
2366 case Stmt::ObjCMessageExprClass:
2372 case Stmt::ObjCAtThrowStmtClass:
2373 case Stmt::CXXThrowExprClass:
2379 case Stmt::ReturnStmtClass:
2385 case Stmt::OffsetOfExprClass: {
2391 for (
const auto Node : PreVisit)
2399 case Stmt::UnaryExprOrTypeTraitExprClass:
2406 case Stmt::StmtExprClass: {
2409 if (SE->getSubStmt()->body_empty()) {
2412 &&
"Empty statement expression must have void type.");
2416 if (
const auto *LastExpr =
2417 dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
2421 state->getSVal(LastExpr,
2427 case Stmt::UnaryOperatorClass: {
2430 if (AMgr.options.ShouldEagerlyAssume && (
U->getOpcode() == UO_LNot)) {
2441 case Stmt::PseudoObjectExprClass: {
2445 if (
const Expr *
Result = PE->getResultExpr()) {
2461 case Expr::ObjCIndirectCopyRestoreExprClass: {
2468 const Expr *E = OIE->getSubExpr();
2483 assert(CalleeSF && CallerSF);
2490 BeforeProcessingCall = N;
2505 if (SP->getStmt() == CE)
2510 if (!BeforeProcessingCall)
2546 NumTimesRetriedWithoutInlining++;
2574 if(AMgr.options.ShouldUnrollLoops) {
2575 unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
2579 Pred, maxBlockVisitOnPath);
2580 if (NewState != Pred->
getState()) {
2581 ExplodedNode *UpdatedNode = Builder.generateNode(BE, NewState, Pred);
2595 if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
2596 AMgr.options.ShouldWidenLoops) {
2598 if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
2612 Builder.generateNode(BE, WidenedState, Pred);
2617 if (BlockCount >= AMgr.options.maxBlockVisitOnPath) {
2621 Builder.generateSink(TaggedLoc, Pred->
getState(), Pred);
2633 Engine.FunctionSummaries->markShouldNotInline(
2640 if ((!AMgr.options.NoRetryExhausted && replayWithoutInlining(Pred, LC)))
2642 NumMaxBlockCountReachedInInlined++;
2644 NumMaxBlockCountReached++;
2647 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
2654 llvm::PrettyStackTraceFormat CrashInfo(
2655 "Processing block entrance B%d -> B%d",
2675 const auto *Ex = dyn_cast<Expr>(
Condition);
2680 bool bitsInit =
false;
2682 while (
const auto *CE = dyn_cast<CastExpr>(Ex)) {
2685 if (!T->isIntegralOrEnumerationType())
2689 if (!bitsInit || newBits < bits) {
2694 Ex = CE->getSubExpr();
2700 if (!bitsInit || !T->isIntegralOrEnumerationType() ||
2704 return state->getSVal(Ex, LCtx);
2710 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2711 if (!BO || !BO->isLogicalOp()) {
2714 Condition = BO->getRHS()->IgnoreParens();
2736 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2739 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2740 if (!BO || !BO->isLogicalOp())
2744 "Other kinds of branches are handled separately!");
2755 std::optional<CFGStmt> CS = Elem.getAs<
CFGStmt>();
2758 const Stmt *LastStmt = CS->getStmt();
2762 llvm_unreachable(
"could not resolve condition");
2766 std::pair<const ObjCForCollectionStmt *, const LocationContext *>;
2773 assert(!State->contains<ObjCForHasMoreIterations>({O, LC}));
2774 return State->set<ObjCForHasMoreIterations>({O, LC}, HasMoreIteraton);
2781 assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
2782 return State->remove<ObjCForHasMoreIterations>({O, LC});
2788 assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
2789 return *State->get<ObjCForHasMoreIterations>({O, LC});
2795static std::optional<std::pair<ProgramStateRef, ProgramStateRef>>
2798 if (
const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(
Condition)) {
2799 bool HasMoreIteraton =
2806 if (HasMoreIteraton)
2807 return std::pair<ProgramStateRef, ProgramStateRef>{State,
nullptr};
2809 return std::pair<ProgramStateRef, ProgramStateRef>{
nullptr, State};
2813 if (
X.isUnknownOrUndef()) {
2815 if (
const auto *Ex = dyn_cast<Expr>(
Condition)) {
2816 if (Ex->getType()->isIntegralOrEnumerationType()) {
2823 N->
getState()->getStateManager().getContext());
2833 if (
X.isUnknownOrUndef())
2834 return std::nullopt;
2839 return State->assume(
V);
2845 std::optional<unsigned> IterationsCompletedInLoop) {
2847 "CXXBindTemporaryExprs are handled by processBindTemporary.");
2856 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2862 "Error evaluating branch");
2868 if (CheckersOutSet.
empty())
2877 std::tie(StTrue, StFalse) = *KnownCondValueAssumption;
2879 if (StTrue && StFalse)
2890 (StTrue && StFalse) ||
2909 bool CompletedTwoIterations = IterationsCompletedInLoop.value_or(0) >= 2;
2910 bool SkipTrueBranch = BothFeasible && CompletedTwoIterations;
2916 if (!SkipTrueBranch || AMgr.options.ShouldWidenLoops) {
2917 Builder.generateNode(StTrue,
true, PredN);
2918 }
else if (!AMgr.options.InlineFunctionsWithAmbiguousLoops) {
2935 Engine.FunctionSummaries->markShouldNotInline(
2954 bool BeforeFirstIteration = IterationsCompletedInLoop == std::optional{0};
2955 bool SkipFalseBranch = BothFeasible && BeforeFirstIteration &&
2956 AMgr.options.ShouldAssumeAtLeastOneIteration;
2957 if (!SkipFalseBranch)
2958 Builder.generateNode(StFalse,
false, PredN);
2966 llvm::ImmutableSet<const VarDecl *>)
2975 bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
2979 state = state->add<InitializedGlobalsSet>(VD);
2982 Builder.generateNode(state, initHasRun, Pred);
3013 Dst.
insert(Engine.makeNode(BE, State, Pred));
3031 State = finishArgumentConstruction(
3046 while (LC != ToLC) {
3047 assert(LC &&
"ToLC must be a parent of FromLC!");
3048 for (
auto I : State->get<ObjectsUnderConstruction>())
3049 if (I.first.getLocationContext() == LC) {
3053 assert(I.first.getItem().getKind() ==
3055 I.first.getItem().getKind() ==
3057 State = State->remove<ObjectsUnderConstruction>(I.first);
3065 Pred = Engine.makeNode(Pred->
getLocation(), State, Pred);
3073 assert(areAllObjectsFullyConstructed(Pred->
getState(),
3083 for (
const auto I : AfterRemovedDead)
3089 Engine.enqueueEndOfFunction(Dst, RS);
3103 assert(SwitchBlock->
succ_size() &&
"Switch must have at least one successor");
3109 llvm::iterator_range<CFGBlock::const_succ_reverse_iterator> CaseBlocks(
3116 Condition->IgnoreParens(), CheckersOutSet, Pred, *
this);
3126 std::optional<NonLoc> CondNL = CondV.
getAs<
NonLoc>();
3128 for (
const CFGBlock *CaseBlock : CaseBlocks) {
3137 assert(V1.getBitWidth() ==
3143 V2 = E->EvaluateKnownConstInt(ACtx);
3150 std::tie(StateMatching, State) =
3151 State->assumeInclusiveRange(*CondNL, V1, V2);
3155 StateMatching = State;
3158 if (StateMatching) {
3159 BlockEdge BE(SwitchBlock, CaseBlock, LCtx);
3160 Dst.
insert(Engine.makeNode(BE, StateMatching, Node));
3182 if (
Condition->IgnoreParenImpCasts()->getType()->isEnumeralType()) {
3183 if (
Switch->isAllEnumCasesCovered())
3187 BlockEdge BE(SwitchBlock, DefaultBlock, LCtx);
3188 Dst.
insert(Engine.makeNode(BE, State, Node));
3204 auto resolveAsLambdaCapturedVar =
3205 [&](
const ValueDecl *VD) -> std::optional<std::pair<SVal, QualType>> {
3206 const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->
getDecl());
3207 const auto *DeclRefEx = dyn_cast<DeclRefExpr>(Ex);
3208 if (AMgr.options.ShouldInlineLambdas && DeclRefEx &&
3209 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
3210 MD->getParent()->isLambda()) {
3213 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
3219 if (
const FieldDecl *FD = LambdaCaptureFields[VD]) {
3222 return std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
3226 return std::nullopt;
3229 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
3232 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
3234 std::optional<std::pair<SVal, QualType>> VInfo =
3235 resolveAsLambdaCapturedVar(VD);
3238 VInfo = std::make_pair(state->getLValue(VD, LocCtxt), VD->getType());
3240 SVal V = VInfo->first;
3241 bool IsReference = VInfo->second->isReferenceType();
3247 V = state->getSVal(R);
3252 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3256 if (
const auto *ED = dyn_cast<EnumConstantDecl>(D)) {
3258 SVal V = svalBuilder.makeIntVal(ED->getInitVal());
3262 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
3263 SVal V = svalBuilder.getFunctionPointer(FD);
3264 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3273 if (
const auto *BD = dyn_cast<BindingDecl>(D)) {
3275 if (std::optional<std::pair<SVal, QualType>> VInfo =
3276 resolveAsLambdaCapturedVar(BD)) {
3277 auto [
V, T] = VInfo.value();
3279 if (T->isReferenceType()) {
3281 V = state->getSVal(R);
3286 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3293 SVal Base = state->getLValue(DD, LCtx);
3294 if (DD->getType()->isReferenceType()) {
3296 Base = state->getSVal(R);
3304 if (
const auto *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
3306 V = state->getLValue(Field,
Base);
3309 else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BD->getBinding())) {
3310 SVal Idx = state->getSVal(ASE->getIdx(), LCtx);
3315 assert(Idx.
isConstant() &&
"BindingDecl array index is not a constant!");
3317 V = state->getLValue(BD->getType(), Idx,
Base);
3320 else if (
const auto *HV = BD->getHoldingVar()) {
3321 V = state->getLValue(HV, LCtx);
3323 if (HV->getType()->isReferenceType()) {
3325 V = state->getSVal(R);
3330 llvm_unreachable(
"An unknown case of structured binding encountered!");
3334 if (BD->getType()->isReferenceType() && !BD->getHoldingVar()) {
3336 V = state->getSVal(R);
3341 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3347 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
3353 llvm_unreachable(
"Support for this Decl not implemented.");
3364 NodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
3368 for (
auto *Node : CheckerPreStmt) {
3413 if (
const auto *ME = dyn_cast<MemberExpr>(Arr)) {
3414 Expr *MEBase = ME->getBase();
3417 if (
auto CXXSCE = dyn_cast<CXXStaticCastExpr>(MEBase)) {
3418 MEBase = CXXSCE->getSubExpr();
3439 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arr))
3444 Base = state->getSVal(R);
3465 NodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
3473 (A->
getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
3475 for (
auto *Node : CheckerPreStmt) {
3479 if (IsGLValueLike) {
3485 if (T->isVoidType())
3488 SVal V = state->getLValue(T,
3489 state->getSVal(Idx, LCtx),
3490 state->getSVal(
Base, LCtx));
3491 Bldr.
generateNode(A, Node, state->BindExpr(A, LCtx,
V),
nullptr,
3493 }
else if (IsVectorType) {
3497 llvm_unreachable(
"Array subscript should be an lValue when not \
3498a vector and not a forbidden lvalue type");
3518 for (
const auto I : CheckedSet)
3521 NodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
3524 for (
const auto I : CheckedSet) {
3530 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member)) {
3531 if (MD->isImplicitObjectMemberFunction())
3532 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
3534 SVal MDVal = svalBuilder.getFunctionPointer(MD);
3535 state = state->BindExpr(M, LCtx, MDVal);
3543 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr,
3550 if (
const auto *SR =
3551 dyn_cast_or_null<SymbolicRegion>(baseExprVal.
getAsRegion())) {
3552 QualType T = SR->getPointeeStaticType();
3558 SVal L = state->getLValue(field, baseExprVal);
3568 dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
3569 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
3570 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
3574 if (field->getType()->isReferenceType()) {
3576 L = state->getSVal(R);
3581 Bldr.
generateNode(M, I, state->BindExpr(M, LCtx, L),
nullptr,
3603 NodeBuilder Bldr(AfterPreSet, AfterInvalidateSet, *currBldrCtx);
3605 for (
const auto I : AfterPreSet) {
3610 for (
unsigned SI = 0, Count = AE->
getNumSubExprs(); SI != Count; SI++) {
3612 SVal SubExprVal = State->getSVal(SubExpr, LCtx);
3613 ValuesToInvalidate.push_back(SubExprVal);
3622 State = State->BindExpr(AE, LCtx, ResultVal);
3642 for (
const std::pair<SVal, SVal> &LocAndVal : LocAndVals) {
3644 const MemRegion *MR = LocAndVal.first.getAsRegion();
3647 Escaped.push_back(LocAndVal.second);
3652 if (
const auto *VR = dyn_cast<VarRegion>(MR->
getBaseRegion()))
3654 VR->getStackFrame()->inTopFrame())
3655 if (
const auto *RD = VR->getValueType()->getAsCXXRecordDecl())
3656 if (!RD->hasTrivialDestructor()) {
3657 Escaped.push_back(LocAndVal.second);
3666 SVal StoredVal = State->getSVal(MR);
3667 if (StoredVal != LocAndVal.second)
3670 Escaped.push_back(LocAndVal.second);
3673 if (Escaped.empty())
3682 std::pair<SVal, SVal> LocAndVal(
Loc, Val);
3693 if (!Invalidated || Invalidated->empty())
3706 for (
const auto I : ExplicitRegions) {
3708 SymbolsDirectlyInvalidated.insert(R->getSymbol());
3712 for (
const auto &sym : *Invalidated) {
3713 if (SymbolsDirectlyInvalidated.count(sym))
3715 SymbolsIndirectlyInvalidated.insert(sym);
3718 if (!SymbolsDirectlyInvalidated.empty())
3723 if (!SymbolsIndirectlyInvalidated.empty())
3743 StoreE, AtDeclInit, *
this, *PP);
3754 Bldr.generateNode(L, state, Pred);
3758 for (
const auto PredI : CheckedSet) {
3766 state = state->bindLoc(location.
castAs<
Loc>(), Val, LC,
3770 if (std::optional<loc::MemRegionVal> LocRegVal =
3772 LocReg = LocRegVal->getRegion();
3776 Bldr.generateNode(L, state, PredI);
3789 const Expr *LocationE,
3795 const Expr *StoreE = AssignE ? AssignE : LocationE;
3799 evalLocation(Tmp, AssignE, LocationE, Pred, state, location,
false);
3807 for (
const auto I : Tmp)
3808 evalBind(Dst, StoreE, I, location, Val,
false);
3813 const Expr *BoundEx,
3819 assert(!
isa<NonLoc>(location) &&
"location cannot be a NonLoc.");
3824 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location,
true);
3833 for (
const auto I : Tmp) {
3834 state = I->getState();
3841 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
3844 Bldr.
generateNode(NodeEx, I, state->BindExpr(BoundEx, LCtx,
V), tag,
3851 const Stmt *BoundEx,
3863 BldrTop.takeNodes(Pred);
3876 Bldr.generateNode(NodeEx, Pred, state, &tag);
3880 NodeEx, BoundEx, *
this);
3881 BldrTop.addNodes(Tmp);
3884std::pair<const ProgramPointTag *, const ProgramPointTag *>
3887 FalseTag(TagProviderName,
"Eagerly Assume False");
3889 return std::make_pair(&TrueTag, &FalseTag);
3913 State = State->set<LastEagerlyAssumeExprIfSuccessful>(
nullptr);
3916 if (SEV && SEV->isExpression()) {
3919 auto [StateTrue, StateFalse] = State->assume(*SEV);
3921 if (StateTrue && StateFalse) {
3922 StateTrue = StateTrue->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3923 StateFalse = StateFalse->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3944 const Expr *Ex)
const {
3945 return Ex && State->get<LastEagerlyAssumeExprIfSuccessful>() == Ex;
3964 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3975 if (std::optional<Loc> LV =
X.getAs<
Loc>())
4006 for (
const auto &
Report : Class.getReports()) {
4007 const auto *PR = dyn_cast<PathSensitiveBugReport>(
Report.get());
4025 llvm::function_ref<
void(
const ExplodedNode *)> PreCallback,
4026 llvm::function_ref<
void(
const ExplodedNode *)> PostCallback,
4048 llvm::raw_string_ostream Out(Buf);
4050 const bool IsDot =
true;
4051 const unsigned int Space = 1;
4054 Out <<
"{ \"state_id\": " << State->getID()
4057 Indent(Out, Space, IsDot) <<
"\"program_points\": [\\l";
4063 Indent(Out, Space + 1, IsDot) <<
"{ ";
4065 Out <<
", \"tag\": ";
4067 Out <<
'\"' << Tag->getDebugTag() <<
'\"';
4070 Out <<
", \"node_id\": " << OtherNode->
getID() <<
4071 ", \"is_sink\": " << OtherNode->
isSink() <<
4079 Indent(Out, Space, IsDot) <<
"],\\l";
4092 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
4096 std::string Filename =
DumpGraph(Nodes);
4097 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
4102 std::vector<const ExplodedNode *> Src;
4105 for (
const auto &
Class : BR.equivalenceClasses()) {
4107 dyn_cast<PathSensitiveBugReport>(
Class.getReports()[0].get());
4110 const auto *N =
const_cast<ExplodedNode *
>(R->getErrorNode());
4117 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
4118 return llvm::WriteGraph(&G,
"ExprEngine",
false,
4120 std::string(Filename));
4124 StringRef Filename) {
4125 std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
4128 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
4133 auto BypassSandbox = llvm::sys::sandbox::scopedDisable();
4134 return llvm::WriteGraph(TrimmedG.get(),
"TrimmedExprEngine",
4136 "Trimmed Exploded Graph",
4137 std::string(Filename));
4141 static int index = 0;
4145void ExprEngine::anchor() { }
4158 bool IsCompound = T->
isArrayType() || T->isRecordType() ||
4159 T->isAnyComplexType() || T->isVectorType();
4161 if (Args.size() > 1 || (E->
isPRValue() && IsCompound && !IsTransparent)) {
4163 for (
Expr *E : llvm::reverse(Args))
4167 S->BindExpr(E, LC, svalBuilder.makeCompoundVal(T, ArgList)));
4173 : S->getSVal(Args.front(), LC)));
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 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 const LocationContext * getInlinedLocationContext(ExplodedNode *Node, ExplodedGraph &G)
Return the innermost location context which is inlined at Node, unless it's the top-level (entry poin...
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.
std::pair< const ObjCForCollectionStmt *, const LocationContext * > ObjCForLctxPair
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 various enumerations that describe declaration and type specifiers.
Defines the Objective-C statement AST node classes.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const clang::PrintingPolicy & getPrintingPolicy() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ParentMap & getParentMap()
ASTContext & getASTContext() const
Stores options for the analyzer from the command line.
AnalysisPurgeMode AnalysisPurgeOpt
Represents a loop initializing the elements of an array.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
static unsigned getNumSubExprs(AtomicOp Op)
Determine the number of arguments the specified atomic builtin should have.
const CFGBlock * getPreviousBlock() const
const CFGBlock * getBlock() const
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
const VarDecl * getVarDecl() const
const Stmt * getTriggerStmt() const
Represents C++ object destructor implicitly generated for base object in destructor.
const CXXBaseSpecifier * getBaseSpecifier() const
Represents a single basic block in a source-level CFG.
succ_reverse_iterator succ_rend()
succ_reverse_iterator succ_rbegin()
CFGTerminator getTerminator() const
Stmt * getTerminatorStmt()
unsigned getBlockID() const
unsigned succ_size() const
Represents C++ object destructor generated from a call to delete.
const CXXDeleteExpr * getDeleteExpr() const
Represents a top-level expression in a basic block.
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
Represents C++ object destructor implicitly generated by compiler on various occasions.
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
Represents C++ base or member initializer from constructor's initialization list.
const CXXCtorInitializer * getInitializer() const
Represents the point where a loop ends.
const Stmt * getLoopStmt() const
Represents C++ object destructor implicitly generated for member object in destructor.
const FieldDecl * getFieldDecl() const
Represents C++ allocator call.
const CXXNewExpr * getAllocatorExpr() const
const Stmt * getStmt() const
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
const CXXBindTemporaryExpr * getBindTemporaryExpr() const
bool isStmtBranch() const
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
const Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a call to a C++ constructor.
Represents a C++ base or member initializer.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
bool isDelegatingInitializer() const
Determine whether this initializer is creating a delegating constructor.
Expr * getInit() const
Get the initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
int64_t getID(const ASTContext &Context) const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a delete expression for memory deallocation and destructor calls, e.g.
SourceLocation getBeginLoc() const
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ destructor within a class.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Represents a point when we begin processing an inlined call.
CaseStmt - Represent a case statement.
Represents a single point (AST node) in the program that requires attention during construction of an...
unsigned getIndex() const
If a single trigger statement triggers multiple constructors, they are usually being enumerated.
const CXXCtorInitializer * getCXXCtorInitializer() const
The construction site is not necessarily a statement.
@ TemporaryDestructorKind
const Stmt * getStmtOrNull() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
const Decl * getSingleDecl() const
Decl - This represents one declaration (or definition), e.g.
This is a meta program point, which should be skipped by all the diagnostic reasoning etc.
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Represents a member of a struct/union/class.
This represents a GCC inline-assembly statement extension.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
ArrayRef< Expr * > inits()
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.
T castAs() const
Convert to the specified ProgramPoint type, asserting that this ProgramPoint is of the desired type.
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 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.
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 (based on CallEvent).
unsigned getIndex() const
const Expr * getCallSite() const
const CFGBlock * getCallSiteBlock() const
bool inTopFrame() const override
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)
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
ExplodedNode * generateNode(ProgramStateRef State, bool branch, ExplodedNode *Pred)
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 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.
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 runCheckersForEndFunction(ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS)
Run checkers on end of function.
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
void runCheckersForBlockEntrance(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const BlockEntrance &Entrance, ExprEngine &Eng) const
Run checkers after taking a control flow edge.
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper &SymReaper)=0
Scan all symbols referenced by the constraints.
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
ExplodedNode * 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...
ExplodedNode * getRoot() const
Get the root node of the graph.
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()
const StackFrameContext * getStackFrame() const
const LocationContext * getLocationContext() const
unsigned succ_size() const
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
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 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).
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.
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)
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.
void processStaticInitializer(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF)
Called by CoreEngine.
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...
AnalysisDeclContextManager & getAnalysisDeclContextManager()
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)
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.
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()
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)
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.
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.
static const ProgramPointTag * cleanupNodeTag()
A tag to track convenience transitions, which can be removed at cleanup.
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
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)
bool didEagerlyAssumeBifurcateAt(ProgramStateRef State, const Expr *Ex) const
ConstraintManager & getConstraintManager()
const NodeBuilderContext & getBuilderContext() const
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.
const LocationContext * getCurrLocationContext() const
Get the 'current' location context corresponding to the current work item (elementary analysis step h...
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 CFGBlock * getCurrBlock() const
Get the 'current' CFGBlock corresponding to the current work item (elementary analysis step handled b...
static ProgramStateRef setWhetherHasMoreIteration(ProgramStateRef State, const ObjCForCollectionStmt *O, const LocationContext *LC, bool HasMoreIteraton)
Note whether this loop has any more iterations to model. These methods.
static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives the size of the array in the pending ArrayInitLoopExpr.
void processIndirectGoto(ExplodedNodeSet &Dst, const Expr *Tgt, const CFGBlock *Dispatch, ExplodedNode *Pred)
processIndirectGoto - Called by CoreEngine.
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
static bool isLocType(QualType T)
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace(ProgramStateRef State) const
Returns the most specific memory space for this memory region in the given ProgramStateRef.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
This is the simplest builder which generates nodes in the ExplodedGraph.
void takeNodes(const ExplodedNodeSet &S)
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Generates a node in the ExplodedGraph.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
void addNodes(const ExplodedNodeSet &S)
While alive, includes the current analysis stack in a crash trace.
Information about invalidation for a particular region/symbol.
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const LocationContext *LCtx, 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.
void markAllDynamicExtentLive(ProgramStateRef State, SymbolReaper &SymReaper)
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState, const LocationContext *LCtx, unsigned BlockCount, ConstCFGElementRef Elem)
Get the states that result from widening the 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 isa(CodeGen::Address addr)
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
@ CXXThis
Parameter for C++ 'this' argument.
Diagnostic wrappers for TextAPI types for error reporting.
Describes how types, statements, expressions, and declarations should be printed.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
Hints for figuring out 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)