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/TimeProfiler.h"
76#include "llvm/Support/raw_ostream.h"
89#define DEBUG_TYPE "ExprEngine"
92 "The # of times RemoveDeadBindings is called");
94 NumMaxBlockCountReached,
95 "The # of aborted paths due to reaching the maximum block count in "
96 "a top level function");
98 NumMaxBlockCountReachedInInlined,
99 "The # of aborted paths due to reaching the maximum block count in "
100 "an inlined function");
102 "The # of times we re-evaluated a call without inlining");
123class ConstructedObjectKey {
124 using ConstructedObjectKeyImpl =
125 std::pair<ConstructionContextItem, const LocationContext *>;
126 const ConstructedObjectKeyImpl Impl;
133 const ConstructionContextItem &getItem()
const {
return Impl.first; }
134 const LocationContext *getLocationContext()
const {
return Impl.second; }
136 ASTContext &getASTContext()
const {
137 return getLocationContext()->getDecl()->getASTContext();
140 void printJson(llvm::raw_ostream &Out, PrinterHelper *Helper,
141 PrintingPolicy &PP)
const {
142 const Stmt *S = getItem().getStmtOrNull();
143 const CXXCtorInitializer *I =
nullptr;
145 I = getItem().getCXXCtorInitializer();
148 Out <<
"\"stmt_id\": " << S->
getID(getASTContext());
150 Out <<
"\"init_id\": " << I->
getID(getASTContext());
153 Out <<
", \"kind\": \"" << getItem().getKindAsString()
154 <<
"\", \"argument_index\": ";
157 Out << getItem().getIndex();
162 Out <<
", \"pretty\": ";
171 void Profile(llvm::FoldingSetNodeID &ID)
const {
173 ID.AddPointer(Impl.second);
176 bool operator==(
const ConstructedObjectKey &RHS)
const {
177 return Impl == RHS.Impl;
180 bool operator<(
const ConstructedObjectKey &RHS)
const {
181 return Impl < RHS.Impl;
186typedef llvm::ImmutableMap<ConstructedObjectKey, SVal>
197typedef llvm::ImmutableMap<
198 std::pair<const CXXConstructExpr *, const LocationContext *>,
unsigned>
199 IndexOfElementToConstructMap;
201 IndexOfElementToConstructMap)
206typedef llvm::ImmutableMap<
207 std::pair<const CXXConstructExpr *, const LocationContext *>,
unsigned>
211typedef llvm::ImmutableMap<const LocationContext *, unsigned>
220static const char* TagProviderName =
"ExprEngine";
225 : CTU(CTU), IsCTUEnabled(mgr.getAnalyzerOptions().IsNaiveCTUEnabled),
227 Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.
getGraph()),
228 StateMgr(
getContext(), mgr.getStoreManagerCreator(),
229 mgr.getConstraintManagerCreator(), G.getAllocator(), this),
231 svalBuilder(StateMgr.
getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
232 BR(mgr, *this), VisitedCallees(VisitedCalleesIn),
233 HowToInline(HowToInlineIn) {
234 unsigned TrimInterval = mgr.
options.GraphTrimInterval;
235 if (TrimInterval != 0) {
237 G.enableNodeReclamation(TrimInterval);
253 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
257 if (!II || !(II->
getName() ==
"main" && FD->getNumParams() > 0))
262 const auto *BT = dyn_cast<BuiltinType>(
T);
263 if (!BT || !BT->isInteger())
266 const MemRegion *R = state->getRegion(PD, InitLoc);
272 svalBuilder.makeZeroVal(
T),
273 svalBuilder.getConditionType());
275 std::optional<DefinedOrUnknownSVal> Constraint =
288 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
292 const MemRegion *R = state->getRegion(SelfD, InitLoc);
295 if (std::optional<Loc> LV =
V.getAs<
Loc>()) {
297 state = state->assume(*LV,
true);
298 assert(state &&
"'self' cannot be null");
302 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
303 if (MD->isImplicitObjectMemberFunction()) {
310 SVal V = state->getSVal(L);
311 if (std::optional<Loc> LV =
V.getAs<
Loc>()) {
312 state = state->assume(*LV,
true);
313 assert(state &&
"'this' cannot be null");
325 const SubRegion **OutRegionWithAdjustments) {
331 SVal InitValWithAdjustments = State->getSVal(InitWithAdjustments, LC);
336 if (OutRegionWithAdjustments)
337 *OutRegionWithAdjustments =
nullptr;
340 Result = InitWithAdjustments;
344 assert(!
isa<Loc>(InitValWithAdjustments) ||
346 Result->getType()->isMemberPointerType());
349 ProgramStateManager &StateMgr = State->getStateManager();
350 MemRegionManager &MRMgr = StateMgr.getRegionManager();
351 StoreManager &StoreMgr = StateMgr.getStoreManager();
374 SmallVector<const Expr *, 2> CommaLHSs;
375 SmallVector<SubobjectAdjustment, 2> Adjustments;
378 CommaLHSs, Adjustments);
385 const TypedValueRegion *TR =
nullptr;
386 if (
const auto *MT = dyn_cast<MaterializeTemporaryExpr>(
Result)) {
388 State = finishObjectConstruction(State, MT, LC);
389 State = State->BindExpr(
Result, LC, *
V);
391 }
else if (
const ValueDecl *VD = MT->getExtendingDecl()) {
397 TR = MRMgr.getCXXStaticLifetimeExtendedObjectRegion(
Init, VD);
399 TR = MRMgr.getCXXLifetimeExtendedObjectRegion(
Init, VD, LC);
403 TR = MRMgr.getCXXTempObjectRegion(
Init, LC);
406 TR = MRMgr.getCXXTempObjectRegion(
Init, LC);
409 SVal Reg = loc::MemRegionVal(TR);
413 for (
const SubobjectAdjustment &Adj : llvm::reverse(Adjustments)) {
424 currBldrCtx->blockCount(), LC,
true,
425 nullptr,
nullptr,
nullptr);
438 SVal InitVal = State->getSVal(
Init, LC);
442 State = State->bindLoc(BaseReg.
castAs<Loc>(), InitVal, LC,
false);
446 if (InitValWithAdjustments.
isUnknown()) {
451 currBldrCtx->blockCount());
454 State->bindLoc(Reg.
castAs<Loc>(), InitValWithAdjustments, LC,
false);
456 State = State->bindLoc(BaseReg.
castAs<Loc>(), InitVal, LC,
false);
462 if (
Result->isGLValue()) {
463 State = State->BindExpr(
Result, LC, Reg);
465 State = State->BindExpr(
Result, LC, InitValWithAdjustments);
471 if (OutRegionWithAdjustments)
478 const LocationContext *LCtx,
unsigned Idx) {
481 assert(!State->contains<IndexOfElementToConstruct>(Key) || Idx > 0);
483 return State->set<IndexOfElementToConstruct>(Key, Idx);
486std::optional<unsigned>
489 const unsigned *
V = State->get<PendingInitLoop>({E, LCtx->
getStackFrame()});
490 return V ? std::make_optional(*
V) : std::nullopt;
498 assert(E && State->contains<PendingInitLoop>(Key));
499 return State->remove<PendingInitLoop>(Key);
508 assert(!State->contains<PendingInitLoop>(Key) && Size > 0);
510 return State->set<PendingInitLoop>(Key, Size);
513std::optional<unsigned>
518 State->get<IndexOfElementToConstruct>({E, LCtx->
getStackFrame()});
519 return V ? std::make_optional(*
V) : std::nullopt;
528 assert(E && State->contains<IndexOfElementToConstruct>(Key));
529 return State->remove<IndexOfElementToConstruct>(Key);
532std::optional<unsigned>
535 assert(LCtx &&
"LocationContext shouldn't be null!");
539 return V ? std::make_optional(*
V) : std::nullopt;
544 assert(LCtx &&
"LocationContext shouldn't be null!");
548 return State->set<PendingArrayDestruction>(Key, Idx);
554 assert(LCtx &&
"LocationContext shouldn't be null!");
558 assert(LCtx && State->contains<PendingArrayDestruction>(Key));
559 return State->remove<PendingArrayDestruction>(Key);
570 if (
auto DS = dyn_cast_or_null<DeclStmt>(Item.
getStmtOrNull())) {
571 if (
auto VD = dyn_cast_or_null<VarDecl>(DS->getSingleDecl()))
572 Init = VD->getInit();
575 if (
auto LE = dyn_cast_or_null<LambdaExpr>(Item.
getStmtOrNull()))
584 if (
const auto *AILE = dyn_cast_or_null<ArrayInitLoopExpr>(
Init))
593 assert((!State->get<ObjectsUnderConstruction>(Key) ||
594 Key.getItem().getKind() ==
596 State->contains<IndexOfElementToConstruct>(
597 {dyn_cast_or_null<CXXConstructExpr>(Init), LC})) &&
598 "The object is already marked as `UnderConstruction`, when it's not "
600 return State->set<ObjectsUnderConstruction>(Key,
V);
608 const SVal *
V = State->get<ObjectsUnderConstruction>(Key);
609 return V ? std::make_optional(*
V) : std::nullopt;
617 assert(State->contains<ObjectsUnderConstruction>(Key));
618 return State->remove<ObjectsUnderConstruction>(Key);
624 ConstructedObjectKey Key({BTE,
true}, LC);
627 return State->set<ObjectsUnderConstruction>(Key,
UnknownVal());
632 const CXXBindTemporaryExpr *BTE,
633 const LocationContext *LC) {
634 ConstructedObjectKey Key({BTE,
true}, LC);
635 assert(State->contains<ObjectsUnderConstruction>(Key));
636 return State->remove<ObjectsUnderConstruction>(Key);
640 const CXXBindTemporaryExpr *BTE,
641 const LocationContext *LC) {
642 ConstructedObjectKey Key({BTE,
true}, LC);
643 return State->contains<ObjectsUnderConstruction>(Key);
647 const LocationContext *FromLC,
648 const LocationContext *ToLC) {
649 const LocationContext *LC = FromLC;
651 assert(LC &&
"ToLC must be a parent of FromLC!");
652 for (
auto I : State->get<ObjectsUnderConstruction>())
653 if (I.first.getLocationContext() == LC)
669 SVal cond,
bool assumption) {
688 unsigned int Space = 0,
bool IsDot =
false) {
693 bool HasItem =
false;
696 const ConstructedObjectKey *LastKey =
nullptr;
697 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
698 const ConstructedObjectKey &Key = I.first;
699 if (Key.getLocationContext() != LCtx)
710 for (
const auto &I : State->get<ObjectsUnderConstruction>()) {
711 const ConstructedObjectKey &Key = I.first;
713 if (Key.getLocationContext() != LCtx)
716 Indent(Out, Space, IsDot) <<
"{ ";
717 Key.printJson(Out,
nullptr, PP);
718 Out <<
", \"value\": \"" <<
Value <<
"\" }";
726 Indent(Out, --Space, IsDot) <<
']';
734 const LocationContext *LCtx,
unsigned int Space = 0,
bool IsDot =
false) {
735 using KeyT = std::pair<const Expr *, const LocationContext *>;
741 bool HasItem =
false;
745 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
746 const KeyT &Key = I.first;
747 if (Key.second != LCtx)
758 for (
const auto &I : State->get<IndexOfElementToConstruct>()) {
759 const KeyT &Key = I.first;
760 unsigned Value = I.second;
761 if (Key.second != LCtx)
764 Indent(Out, Space, IsDot) <<
"{ ";
767 const Expr *E = Key.first;
768 Out <<
"\"stmt_id\": " << E->
getID(Context);
771 Out <<
", \"kind\": null";
774 Out <<
", \"pretty\": ";
780 Out <<
", \"value\": \"Current index: " <<
Value - 1 <<
"\" }";
788 Indent(Out, --Space, IsDot) <<
']';
797 unsigned int Space = 0,
798 bool IsDot =
false) {
799 using KeyT = std::pair<const CXXConstructExpr *, const LocationContext *>;
805 bool HasItem =
false;
809 for (
const auto &I : State->get<PendingInitLoop>()) {
810 const KeyT &Key = I.first;
811 if (Key.second != LCtx)
822 for (
const auto &I : State->get<PendingInitLoop>()) {
823 const KeyT &Key = I.first;
824 unsigned Value = I.second;
825 if (Key.second != LCtx)
828 Indent(Out, Space, IsDot) <<
"{ ";
831 Out <<
"\"stmt_id\": " << E->
getID(Context);
833 Out <<
", \"kind\": null";
834 Out <<
", \"pretty\": ";
840 Out <<
", \"value\": \"Flattened size: " <<
Value <<
"\"}";
848 Indent(Out, --Space, IsDot) <<
']';
857 unsigned int Space = 0,
bool IsDot =
false) {
861 bool HasItem =
false;
864 KeyT LastKey =
nullptr;
865 for (
const auto &I : State->get<PendingArrayDestruction>()) {
866 const KeyT &Key = I.first;
878 for (
const auto &I : State->get<PendingArrayDestruction>()) {
879 const KeyT &Key = I.first;
883 Indent(Out, Space, IsDot) <<
"{ ";
885 Out <<
"\"stmt_id\": null";
886 Out <<
", \"kind\": null";
887 Out <<
", \"pretty\": \"Current index: \"";
888 Out <<
", \"value\": \"" << I.second <<
"\" }";
896 Indent(Out, --Space, IsDot) <<
']';
910template <
typename Trait,
typename Printer,
typename... Args>
913 const char *NL,
unsigned int Space,
bool IsDot,
914 const char *jsonPropertyName, Printer printer, Args &&...args) {
922 static_assert(std::is_function_v<std::remove_pointer_t<Printer>>,
923 "Printer is not a function!");
924 static_assert(std::is_convertible_v<Printer, RequiredType>,
925 "Printer doesn't have the required type!");
927 if (LCtx && !State->get<Trait>().isEmpty()) {
928 Indent(Out, Space, IsDot) <<
'\"' << jsonPropertyName <<
"\": ";
932 printer(Out, State, NL, LC, Space, IsDot, std::forward<Args>(args)...);
936 Indent(Out, Space, IsDot) <<
"]," << NL;
942 unsigned int Space,
bool IsDot)
const {
945 Out, State, LCtx, NL, Space, IsDot,
"constructing_objects",
948 Out, State, LCtx, NL, Space, IsDot,
"index_of_element",
951 Out, State, LCtx, NL, Space, IsDot,
"pending_init_loops",
954 Out, State, LCtx, NL, Space, IsDot,
"pending_destructors",
969 currStmtIdx = StmtIdx;
1030 const Stmt *ReferenceStmt,
1032 const Stmt *DiagnosticStmt,
1034 llvm::TimeTraceScope TimeScope(
"ExprEngine::removeDead");
1037 &&
"PostStmt is not generally supported by the SymbolReaper yet");
1038 assert(LC &&
"Must pass the current (or expiring) LocationContext");
1040 if (!DiagnosticStmt) {
1041 DiagnosticStmt = ReferenceStmt;
1042 assert(DiagnosticStmt &&
"Required for clearing a LocationContext");
1045 NumRemoveDeadBindings++;
1051 if (!ReferenceStmt) {
1053 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
1060 for (
auto I : CleanedState->get<ObjectsUnderConstruction>()) {
1061 if (
SymbolRef Sym = I.second.getAsSymbol())
1063 if (
const MemRegion *MR = I.second.getAsRegion())
1072 CleanedState = StateMgr.removeDeadBindingsFromEnvironmentAndStore(
1073 CleanedState, SFC, SymReaper);
1080 DiagnosticStmt, *
this, K);
1091 for (
const auto I : CheckedSet) {
1098 assert(StateMgr.haveEqualEnvironments(CheckerState, Pred->
getState()) &&
1099 "Checkers are not allowed to modify the Environment as a part of "
1100 "checkDeadSymbols processing.");
1101 assert(StateMgr.haveEqualStores(CheckerState, Pred->
getState()) &&
1102 "Checkers are not allowed to modify the Store as a part of "
1103 "checkDeadSymbols processing.");
1108 StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
1120 G.reclaimRecentlyAllocatedNodes();
1124 "Error evaluating statement");
1133 CleanedStates.
Add(Pred);
1137 for (
const auto I : CleanedStates) {
1140 Visit(currStmt, I, DstI);
1145 Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
1151 "Error evaluating end of the loop");
1157 if(AMgr.options.ShouldUnrollLoops)
1163 Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
1174 "Error evaluating initializer");
1181 SVal thisVal = State->getSVal(svalBuilder.getCXXThis(
decl, stackFrame));
1193 State = finishObjectConstruction(State, BMI, LC);
1204 FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
1208 if (
Init->getType()->isArrayType()) {
1212 while ((ASE = dyn_cast<ArraySubscriptExpr>(
Init)))
1215 InitVal = State->getSVal(
Init, stackFrame);
1222 Field->getType(), currBldrCtx->blockCount());
1225 InitVal = State->getSVal(BMI->
getInit(), stackFrame);
1229 evalBind(Tmp,
Init, Pred, FieldLoc, InitVal,
true, &PP);
1237 SVal InitVal = State->getSVal(
Init, stackFrame);
1238 evalBind(Tmp,
Init, Pred, BaseLoc, InitVal,
true);
1250 for (
const auto I : Tmp) {
1256 Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
1259std::pair<ProgramStateRef, uint64_t>
1260ExprEngine::prepareStateForArrayDestruction(
const ProgramStateRef State,
1264 SVal *ElementCountVal) {
1265 assert(Region !=
nullptr &&
"Not-null region expected");
1268 while (
const auto *NTy = dyn_cast<ArrayType>(Ty))
1269 Ty = NTy->getElementType().getDesugaredType(
getContext());
1273 if (ElementCountVal)
1274 *ElementCountVal = ElementCount;
1282 if (!ElementCount.isConstant())
1285 Idx = ElementCount.getAsInteger()->getLimitedValue();
1293 return {setPendingArrayDestruction(State, LCtx, Idx), Idx};
1316 llvm_unreachable(
"Unexpected dtor kind.");
1320 Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
1331 if (Opts.MayInlineCXXAllocator)
1340 Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
1357 const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
1372 std::tie(state, Idx) = prepareStateForArrayDestruction(
1373 state, Region, varType, LCtx, &ElementCount);
1375 if (ElementCount.isConstant()) {
1376 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1377 assert(ArrayLength &&
1378 "An automatic dtor for a 0 length array shouldn't be triggered!");
1383 "ExprEngine",
"Skipping automatic 0 length array destruction, "
1384 "which shouldn't be in the CFG.");
1402 "Prepare for object destruction");
1412 false, Pred, Dst, CallOpts);
1423 SVal ArgVal = State->getSVal(Arg, LCtx);
1427 if (State->isNull(ArgVal).isConstrainedTrue()) {
1438 auto getDtorDecl = [](
const QualType &DTy) {
1450 while (
const auto *AT =
getContext().getAsArrayType(DTy))
1451 DTy = AT->getElementType();
1455 std::tie(State, Idx) = prepareStateForArrayDestruction(
1456 State, ArgR, DTy, LCtx, &ElementCount);
1460 if (ElementCount.isConstant() &&
1461 ElementCount.getAsInteger()->getLimitedValue() == 0) {
1464 "ExprEngine",
"Skipping 0 length array delete destruction");
1472 ArgR = State->getLValue(DTy, svalBuilder.makeArrayIndex(Idx), ArgVal)
1479 "Prepare for object destruction");
1508 true, Pred, Dst, CallOpts);
1520 Loc ThisStorageLoc =
1522 Loc ThisLoc = State->getSVal(ThisStorageLoc).
castAs<
Loc>();
1523 SVal FieldVal = State->getLValue(
Member, ThisLoc);
1528 std::tie(State, Idx) = prepareStateForArrayDestruction(
1529 State, FieldVal.getAsRegion(),
T, LCtx, &ElementCount);
1531 if (ElementCount.isConstant()) {
1532 uint64_t ArrayLength = ElementCount.getAsInteger()->getLimitedValue();
1533 assert(ArrayLength &&
1534 "A member dtor for a 0 length array shouldn't be triggered!");
1539 "ExprEngine",
"Skipping member 0 length array destruction, which "
1540 "shouldn't be in the CFG.");
1557 "Prepare for object destruction");
1567 false, Pred, Dst, CallOpts);
1585 MR =
V->getAsRegion();
1590 if (isDestructorElided(State, BTE, LC)) {
1591 State = cleanupElidedDestructor(State, BTE, LC);
1607 assert(CleanDtorState.
size() <= 1);
1609 CleanDtorState.
empty() ? Pred : *CleanDtorState.
begin();
1632 T = AT->getElementType();
1643 false, CleanPred, Dst, CallOpts);
1683 State = addObjectUnderConstruction(State, BTE, LC,
UnknownVal());
1693 class CollectReachableSymbolsCallback final :
public SymbolVisitor {
1698 : Symbols(Symbols) {}
1702 bool VisitSymbol(
SymbolRef Sym)
override {
1703 Symbols.insert(Sym);
1708 CollectReachableSymbolsCallback CallBack(Symbols);
1710 State->scanReachableSymbols(
V, CallBack);
1713 State, CallBack.getSymbols(),
Call, K,
nullptr);
1727 case Stmt::CXXDependentScopeMemberExprClass:
1728 case Stmt::CXXTryStmtClass:
1729 case Stmt::CXXTypeidExprClass:
1730 case Stmt::CXXUuidofExprClass:
1731 case Stmt::CXXFoldExprClass:
1732 case Stmt::MSPropertyRefExprClass:
1733 case Stmt::MSPropertySubscriptExprClass:
1734 case Stmt::CXXUnresolvedConstructExprClass:
1735 case Stmt::DependentScopeDeclRefExprClass:
1736 case Stmt::ArrayTypeTraitExprClass:
1737 case Stmt::ExpressionTraitExprClass:
1738 case Stmt::UnresolvedLookupExprClass:
1739 case Stmt::UnresolvedMemberExprClass:
1740 case Stmt::RecoveryExprClass:
1741 case Stmt::CXXNoexceptExprClass:
1742 case Stmt::PackExpansionExprClass:
1743 case Stmt::PackIndexingExprClass:
1744 case Stmt::SubstNonTypeTemplateParmPackExprClass:
1745 case Stmt::FunctionParmPackExprClass:
1746 case Stmt::CoroutineBodyStmtClass:
1747 case Stmt::CoawaitExprClass:
1748 case Stmt::DependentCoawaitExprClass:
1749 case Stmt::CoreturnStmtClass:
1750 case Stmt::CoyieldExprClass:
1751 case Stmt::SEHTryStmtClass:
1752 case Stmt::SEHExceptStmtClass:
1753 case Stmt::SEHLeaveStmtClass:
1754 case Stmt::SEHFinallyStmtClass:
1755 case Stmt::OMPCanonicalLoopClass:
1756 case Stmt::OMPParallelDirectiveClass:
1757 case Stmt::OMPSimdDirectiveClass:
1758 case Stmt::OMPForDirectiveClass:
1759 case Stmt::OMPForSimdDirectiveClass:
1760 case Stmt::OMPSectionsDirectiveClass:
1761 case Stmt::OMPSectionDirectiveClass:
1762 case Stmt::OMPScopeDirectiveClass:
1763 case Stmt::OMPSingleDirectiveClass:
1764 case Stmt::OMPMasterDirectiveClass:
1765 case Stmt::OMPCriticalDirectiveClass:
1766 case Stmt::OMPParallelForDirectiveClass:
1767 case Stmt::OMPParallelForSimdDirectiveClass:
1768 case Stmt::OMPParallelSectionsDirectiveClass:
1769 case Stmt::OMPParallelMasterDirectiveClass:
1770 case Stmt::OMPParallelMaskedDirectiveClass:
1771 case Stmt::OMPTaskDirectiveClass:
1772 case Stmt::OMPTaskyieldDirectiveClass:
1773 case Stmt::OMPBarrierDirectiveClass:
1774 case Stmt::OMPTaskwaitDirectiveClass:
1775 case Stmt::OMPErrorDirectiveClass:
1776 case Stmt::OMPTaskgroupDirectiveClass:
1777 case Stmt::OMPFlushDirectiveClass:
1778 case Stmt::OMPDepobjDirectiveClass:
1779 case Stmt::OMPScanDirectiveClass:
1780 case Stmt::OMPOrderedDirectiveClass:
1781 case Stmt::OMPAtomicDirectiveClass:
1782 case Stmt::OMPAssumeDirectiveClass:
1783 case Stmt::OMPTargetDirectiveClass:
1784 case Stmt::OMPTargetDataDirectiveClass:
1785 case Stmt::OMPTargetEnterDataDirectiveClass:
1786 case Stmt::OMPTargetExitDataDirectiveClass:
1787 case Stmt::OMPTargetParallelDirectiveClass:
1788 case Stmt::OMPTargetParallelForDirectiveClass:
1789 case Stmt::OMPTargetUpdateDirectiveClass:
1790 case Stmt::OMPTeamsDirectiveClass:
1791 case Stmt::OMPCancellationPointDirectiveClass:
1792 case Stmt::OMPCancelDirectiveClass:
1793 case Stmt::OMPTaskLoopDirectiveClass:
1794 case Stmt::OMPTaskLoopSimdDirectiveClass:
1795 case Stmt::OMPMasterTaskLoopDirectiveClass:
1796 case Stmt::OMPMaskedTaskLoopDirectiveClass:
1797 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
1798 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
1799 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
1800 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
1801 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1802 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
1803 case Stmt::OMPDistributeDirectiveClass:
1804 case Stmt::OMPDistributeParallelForDirectiveClass:
1805 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1806 case Stmt::OMPDistributeSimdDirectiveClass:
1807 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1808 case Stmt::OMPTargetSimdDirectiveClass:
1809 case Stmt::OMPTeamsDistributeDirectiveClass:
1810 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1811 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1812 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1813 case Stmt::OMPTargetTeamsDirectiveClass:
1814 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1815 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1816 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1817 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1818 case Stmt::OMPReverseDirectiveClass:
1819 case Stmt::OMPStripeDirectiveClass:
1820 case Stmt::OMPTileDirectiveClass:
1821 case Stmt::OMPInterchangeDirectiveClass:
1822 case Stmt::OMPFuseDirectiveClass:
1823 case Stmt::OMPInteropDirectiveClass:
1824 case Stmt::OMPDispatchDirectiveClass:
1825 case Stmt::OMPMaskedDirectiveClass:
1826 case Stmt::OMPGenericLoopDirectiveClass:
1827 case Stmt::OMPTeamsGenericLoopDirectiveClass:
1828 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
1829 case Stmt::OMPParallelGenericLoopDirectiveClass:
1830 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
1831 case Stmt::CapturedStmtClass:
1832 case Stmt::SYCLKernelCallStmtClass:
1833 case Stmt::OpenACCComputeConstructClass:
1834 case Stmt::OpenACCLoopConstructClass:
1835 case Stmt::OpenACCCombinedConstructClass:
1836 case Stmt::OpenACCDataConstructClass:
1837 case Stmt::OpenACCEnterDataConstructClass:
1838 case Stmt::OpenACCExitDataConstructClass:
1839 case Stmt::OpenACCHostDataConstructClass:
1840 case Stmt::OpenACCWaitConstructClass:
1841 case Stmt::OpenACCCacheConstructClass:
1842 case Stmt::OpenACCInitConstructClass:
1843 case Stmt::OpenACCShutdownConstructClass:
1844 case Stmt::OpenACCSetConstructClass:
1845 case Stmt::OpenACCUpdateConstructClass:
1846 case Stmt::OpenACCAtomicConstructClass:
1847 case Stmt::OMPUnrollDirectiveClass:
1848 case Stmt::OMPMetaDirectiveClass:
1849 case Stmt::HLSLOutArgExprClass: {
1851 Engine.addAbortedBlock(node, currBldrCtx->getBlock());
1855 case Stmt::ParenExprClass:
1856 llvm_unreachable(
"ParenExprs already handled.");
1857 case Stmt::GenericSelectionExprClass:
1858 llvm_unreachable(
"GenericSelectionExprs already handled.");
1861 case Stmt::BreakStmtClass:
1862 case Stmt::CaseStmtClass:
1863 case Stmt::CompoundStmtClass:
1864 case Stmt::ContinueStmtClass:
1865 case Stmt::CXXForRangeStmtClass:
1866 case Stmt::DefaultStmtClass:
1867 case Stmt::DoStmtClass:
1868 case Stmt::ForStmtClass:
1869 case Stmt::GotoStmtClass:
1870 case Stmt::IfStmtClass:
1871 case Stmt::IndirectGotoStmtClass:
1872 case Stmt::LabelStmtClass:
1874 case Stmt::NullStmtClass:
1875 case Stmt::SwitchStmtClass:
1876 case Stmt::WhileStmtClass:
1877 case Stmt::DeferStmtClass:
1878 case Expr::MSDependentExistsStmtClass:
1879 llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
1880 case Stmt::ImplicitValueInitExprClass:
1884 llvm_unreachable(
"Should be pruned from CFG");
1886 case Stmt::ObjCSubscriptRefExprClass:
1887 case Stmt::ObjCPropertyRefExprClass:
1888 llvm_unreachable(
"These are handled by PseudoObjectExpr");
1890 case Stmt::GNUNullExprClass: {
1893 state = state->BindExpr(
1895 svalBuilder.makeIntValWithWidth(
getContext().VoidPtrTy, 0));
1900 case Stmt::ObjCAtSynchronizedStmtClass:
1906 case Expr::ConstantExprClass:
1907 case Stmt::ExprWithCleanupsClass:
1911 case Stmt::CXXBindTemporaryExprClass: {
1922 case Stmt::ArrayInitLoopExprClass:
1928 case Stmt::DesignatedInitExprClass:
1929 case Stmt::DesignatedInitUpdateExprClass:
1930 case Stmt::ArrayInitIndexExprClass:
1931 case Stmt::ExtVectorElementExprClass:
1932 case Stmt::ImaginaryLiteralClass:
1933 case Stmt::ObjCAtCatchStmtClass:
1934 case Stmt::ObjCAtFinallyStmtClass:
1935 case Stmt::ObjCAtTryStmtClass:
1936 case Stmt::ObjCAutoreleasePoolStmtClass:
1937 case Stmt::ObjCEncodeExprClass:
1938 case Stmt::ObjCIsaExprClass:
1939 case Stmt::ObjCProtocolExprClass:
1940 case Stmt::ObjCSelectorExprClass:
1941 case Stmt::ParenListExprClass:
1942 case Stmt::ShuffleVectorExprClass:
1943 case Stmt::ConvertVectorExprClass:
1944 case Stmt::VAArgExprClass:
1945 case Stmt::CUDAKernelCallExprClass:
1946 case Stmt::OpaqueValueExprClass:
1947 case Stmt::AsTypeExprClass:
1948 case Stmt::ConceptSpecializationExprClass:
1949 case Stmt::CXXRewrittenBinaryOperatorClass:
1950 case Stmt::RequiresExprClass:
1951 case Stmt::EmbedExprClass:
1956 case Stmt::PredefinedExprClass:
1957 case Stmt::AddrLabelExprClass:
1958 case Stmt::IntegerLiteralClass:
1959 case Stmt::FixedPointLiteralClass:
1960 case Stmt::CharacterLiteralClass:
1961 case Stmt::CXXScalarValueInitExprClass:
1962 case Stmt::CXXBoolLiteralExprClass:
1963 case Stmt::ObjCBoolLiteralExprClass:
1964 case Stmt::ObjCAvailabilityCheckExprClass:
1965 case Stmt::FloatingLiteralClass:
1966 case Stmt::NoInitExprClass:
1967 case Stmt::SizeOfPackExprClass:
1968 case Stmt::StringLiteralClass:
1969 case Stmt::SourceLocExprClass:
1970 case Stmt::ObjCStringLiteralClass:
1971 case Stmt::CXXPseudoDestructorExprClass:
1972 case Stmt::SubstNonTypeTemplateParmExprClass:
1973 case Stmt::CXXNullPtrLiteralExprClass:
1974 case Stmt::ArraySectionExprClass:
1975 case Stmt::OMPArrayShapingExprClass:
1976 case Stmt::OMPIteratorExprClass:
1977 case Stmt::SYCLUniqueStableNameExprClass:
1978 case Stmt::OpenACCAsteriskSizeExprClass:
1979 case Stmt::TypeTraitExprClass: {
1988 case Stmt::AttributedStmtClass: {
1995 case Stmt::CXXDefaultArgExprClass:
1996 case Stmt::CXXDefaultInitExprClass: {
2005 if (
const auto *DefE = dyn_cast<CXXDefaultArgExpr>(S))
2006 ArgE = DefE->getExpr();
2007 else if (
const auto *DefE = dyn_cast<CXXDefaultInitExpr>(S))
2008 ArgE = DefE->getExpr();
2010 llvm_unreachable(
"unknown constant wrapper kind");
2012 bool IsTemporary =
false;
2013 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
2014 ArgE = MTE->getSubExpr();
2018 std::optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE);
2023 for (
const auto I : PreVisit) {
2025 State = State->BindExpr(S, LCtx, *ConstantVal);
2027 State = createTemporaryRegionIfNeeded(State, LCtx,
2039 case Stmt::CXXStdInitializerListExprClass:
2040 case Expr::ObjCArrayLiteralClass:
2041 case Expr::ObjCDictionaryLiteralClass:
2042 case Expr::ObjCBoxedExprClass: {
2052 QualType resultType = Ex->getType();
2054 for (
const auto N : preVisit) {
2056 SVal result = svalBuilder.conjureSymbolVal(
2058 currBldrCtx->blockCount());
2066 for (
auto Child : Ex->children()) {
2068 SVal Val = State->getSVal(Child, LCtx);
2080 case Stmt::ArraySubscriptExprClass:
2086 case Stmt::MatrixSingleSubscriptExprClass:
2088 "Support for MatrixSingleSubscriptExprClass is not implemented.");
2091 case Stmt::MatrixSubscriptExprClass:
2092 llvm_unreachable(
"Support for MatrixSubscriptExpr is not implemented.");
2095 case Stmt::GCCAsmStmtClass: {
2107 case Stmt::MSAsmStmtClass:
2113 case Stmt::BlockExprClass:
2119 case Stmt::LambdaExprClass:
2120 if (AMgr.options.ShouldInlineLambdas) {
2126 Engine.addAbortedBlock(node, currBldrCtx->getBlock());
2130 case Stmt::BinaryOperatorClass: {
2132 if (B->isLogicalOp()) {
2138 else if (B->getOpcode() == BO_Comma) {
2142 state->getSVal(B->getRHS(),
2149 if (AMgr.options.ShouldEagerlyAssume &&
2150 (B->isRelationalOp() || B->isEqualityOp())) {
2162 case Stmt::CXXOperatorCallExprClass: {
2167 const Decl *Callee = OCE->getCalleeDecl();
2168 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
2169 if (MD->isImplicitObjectMemberFunction()) {
2173 createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
2174 if (NewState != State) {
2186 case Stmt::CallExprClass:
2187 case Stmt::CXXMemberCallExprClass:
2188 case Stmt::UserDefinedLiteralClass:
2194 case Stmt::CXXCatchStmtClass:
2200 case Stmt::CXXTemporaryObjectExprClass:
2201 case Stmt::CXXConstructExprClass:
2207 case Stmt::CXXInheritedCtorInitExprClass:
2214 case Stmt::CXXNewExprClass: {
2221 for (
const auto i : PreVisit)
2229 case Stmt::CXXDeleteExprClass: {
2237 for (
const auto i : PostVisit)
2246 case Stmt::ChooseExprClass: {
2254 case Stmt::CompoundAssignOperatorClass:
2260 case Stmt::CompoundLiteralExprClass:
2266 case Stmt::BinaryConditionalOperatorClass:
2267 case Stmt::ConditionalOperatorClass: {
2275 case Stmt::CXXThisExprClass:
2281 case Stmt::DeclRefExprClass: {
2289 case Stmt::DeclStmtClass:
2295 case Stmt::ImplicitCastExprClass:
2296 case Stmt::CStyleCastExprClass:
2297 case Stmt::CXXStaticCastExprClass:
2298 case Stmt::CXXDynamicCastExprClass:
2299 case Stmt::CXXReinterpretCastExprClass:
2300 case Stmt::CXXConstCastExprClass:
2301 case Stmt::CXXFunctionalCastExprClass:
2302 case Stmt::BuiltinBitCastExprClass:
2303 case Stmt::ObjCBridgedCastExprClass:
2304 case Stmt::CXXAddrspaceCastExprClass: {
2316 case Expr::MaterializeTemporaryExprClass: {
2322 for (
const auto i : dstPrevisit)
2329 case Stmt::InitListExprClass: {
2337 case Expr::CXXParenListInitExprClass: {
2346 case Stmt::MemberExprClass:
2352 case Stmt::AtomicExprClass:
2358 case Stmt::ObjCIvarRefExprClass:
2364 case Stmt::ObjCForCollectionStmtClass:
2370 case Stmt::ObjCMessageExprClass:
2376 case Stmt::ObjCAtThrowStmtClass:
2377 case Stmt::CXXThrowExprClass:
2383 case Stmt::ReturnStmtClass:
2389 case Stmt::OffsetOfExprClass: {
2395 for (
const auto Node : PreVisit)
2403 case Stmt::UnaryExprOrTypeTraitExprClass:
2410 case Stmt::StmtExprClass: {
2413 if (SE->getSubStmt()->body_empty()) {
2416 &&
"Empty statement expression must have void type.");
2420 if (
const auto *LastExpr =
2421 dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
2425 state->getSVal(LastExpr,
2431 case Stmt::UnaryOperatorClass: {
2434 if (AMgr.options.ShouldEagerlyAssume && (
U->getOpcode() == UO_LNot)) {
2445 case Stmt::PseudoObjectExprClass: {
2449 if (
const Expr *
Result = PE->getResultExpr()) {
2463 case Expr::ObjCIndirectCopyRestoreExprClass: {
2470 const Expr *E = OIE->getSubExpr();
2484 assert(CalleeSF && CallerSF);
2491 BeforeProcessingCall = N;
2506 if (SP->getStmt() == CE)
2511 if (!BeforeProcessingCall)
2540 NumTimesRetriedWithoutInlining++;
2564 if(AMgr.options.ShouldUnrollLoops) {
2565 unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
2569 Pred, maxBlockVisitOnPath);
2570 if (NewState != Pred->
getState()) {
2585 if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
2586 AMgr.options.ShouldWidenLoops) {
2588 if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
2608 if (BlockCount >= AMgr.options.maxBlockVisitOnPath) {
2623 Engine.FunctionSummaries->markShouldNotInline(
2630 if ((!AMgr.options.NoRetryExhausted && replayWithoutInlining(Pred, LC)))
2632 NumMaxBlockCountReachedInInlined++;
2634 NumMaxBlockCountReached++;
2637 Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
2645 llvm::PrettyStackTraceFormat CrashInfo(
2646 "Processing block entrance B%d -> B%d",
2649 currBldrCtx = &BldCtx;
2651 currBldrCtx =
nullptr;
2668 const auto *Ex = dyn_cast<Expr>(
Condition);
2673 bool bitsInit =
false;
2675 while (
const auto *CE = dyn_cast<CastExpr>(Ex)) {
2678 if (!
T->isIntegralOrEnumerationType())
2682 if (!bitsInit || newBits < bits) {
2687 Ex = CE->getSubExpr();
2693 if (!bitsInit || !
T->isIntegralOrEnumerationType() ||
2697 return state->getSVal(Ex, LCtx);
2703 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2704 if (!BO || !BO->isLogicalOp()) {
2707 Condition = BO->getRHS()->IgnoreParens();
2729 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2732 const auto *BO = dyn_cast<BinaryOperator>(
Condition);
2733 if (!BO || !BO->isLogicalOp())
2737 "Other kinds of branches are handled separately!");
2748 std::optional<CFGStmt> CS = Elem.getAs<
CFGStmt>();
2751 const Stmt *LastStmt = CS->getStmt();
2755 llvm_unreachable(
"could not resolve condition");
2759 std::pair<const ObjCForCollectionStmt *, const LocationContext *>;
2766 assert(!State->contains<ObjCForHasMoreIterations>({O, LC}));
2767 return State->set<ObjCForHasMoreIterations>({O, LC}, HasMoreIteraton);
2774 assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
2775 return State->remove<ObjCForHasMoreIterations>({O, LC});
2781 assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
2782 return *State->get<ObjCForHasMoreIterations>({O, LC});
2788static std::optional<std::pair<ProgramStateRef, ProgramStateRef>>
2791 if (
const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(
Condition)) {
2792 bool HasMoreIteraton =
2799 if (HasMoreIteraton)
2800 return std::pair<ProgramStateRef, ProgramStateRef>{State,
nullptr};
2802 return std::pair<ProgramStateRef, ProgramStateRef>{
nullptr, State};
2806 if (
X.isUnknownOrUndef()) {
2808 if (
const auto *Ex = dyn_cast<Expr>(
Condition)) {
2809 if (Ex->getType()->isIntegralOrEnumerationType()) {
2816 N->
getState()->getStateManager().getContext());
2826 if (
X.isUnknownOrUndef())
2827 return std::nullopt;
2832 return State->assume(
V);
2838 std::optional<unsigned> IterationsCompletedInLoop) {
2840 "CXXBindTemporaryExprs are handled by processBindTemporary.");
2841 currBldrCtx = &BldCtx;
2850 if (
const auto *Ex = dyn_cast<Expr>(
Condition))
2856 "Error evaluating branch");
2862 if (CheckersOutSet.
empty())
2867 if (PredN->isSink())
2874 std::tie(StTrue, StFalse) = *KnownCondValueAssumption;
2876 if (StTrue && StFalse)
2887 (StTrue && StFalse) ||
2906 bool CompletedTwoIterations = IterationsCompletedInLoop.value_or(0) >= 2;
2907 bool SkipTrueBranch = BothFeasible && CompletedTwoIterations;
2913 if (!SkipTrueBranch || AMgr.options.ShouldWidenLoops) {
2914 Builder.generateNode(StTrue,
true, PredN);
2915 }
else if (!AMgr.options.InlineFunctionsWithAmbiguousLoops) {
2932 Engine.FunctionSummaries->markShouldNotInline(
2951 bool BeforeFirstIteration = IterationsCompletedInLoop == std::optional{0};
2952 bool SkipFalseBranch = BothFeasible && BeforeFirstIteration &&
2953 AMgr.options.ShouldAssumeAtLeastOneIteration;
2954 if (!SkipFalseBranch)
2955 Builder.generateNode(StFalse,
false, PredN);
2958 currBldrCtx =
nullptr;
2964 llvm::ImmutableSet<const VarDecl *>)
2969 currBldrCtx = &BuilderCtx;
2973 bool initHasRun = state->contains<InitializedGlobalsSet>(VD);
2977 state = state->add<InitializedGlobalsSet>(VD);
2980 Builder.generateNode(state, initHasRun, Pred);
2982 currBldrCtx =
nullptr;
3004 if (Succ.getLabel() == L) {
3005 builder.generateNode(Succ, state);
3010 llvm_unreachable(
"No block with label.");
3044 State = finishArgumentConstruction(
3059 while (LC != ToLC) {
3060 assert(LC &&
"ToLC must be a parent of FromLC!");
3061 for (
auto I : State->get<ObjectsUnderConstruction>())
3062 if (I.first.getLocationContext() == LC) {
3066 assert(I.first.getItem().getKind() ==
3068 I.first.getItem().getKind() ==
3070 State = State->remove<ObjectsUnderConstruction>(I.first);
3088 assert(areAllObjectsFullyConstructed(Pred->
getState(),
3098 for (
const auto I : AfterRemovedDead)
3104 Engine.enqueueEndOfFunction(Dst, RS);
3116 if (CondV_untested.
isUndef()) {
3128 bool defaultIsFeasible = I == EI;
3130 for ( ; I != EI; ++I) {
3135 const CaseStmt *Case = I.getCase();
3149 if (std::optional<NonLoc> NL = CondV.
getAs<
NonLoc>())
3150 std::tie(StateCase, DefaultSt) =
3151 DefaultSt->assumeInclusiveRange(*NL, V1, V2);
3153 StateCase = DefaultSt;
3161 defaultIsFeasible =
true;
3163 defaultIsFeasible =
false;
3168 if (!defaultIsFeasible)
3200 auto resolveAsLambdaCapturedVar =
3201 [&](
const ValueDecl *VD) -> std::optional<std::pair<SVal, QualType>> {
3202 const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->
getDecl());
3203 const auto *DeclRefEx = dyn_cast<DeclRefExpr>(Ex);
3204 if (AMgr.options.ShouldInlineLambdas && DeclRefEx &&
3205 DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
3206 MD->getParent()->isLambda()) {
3209 llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
3215 if (
const FieldDecl *FD = LambdaCaptureFields[VD]) {
3218 return std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
3222 return std::nullopt;
3225 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
3228 assert(Ex->
isGLValue() || VD->getType()->isVoidType());
3230 std::optional<std::pair<SVal, QualType>> VInfo =
3231 resolveAsLambdaCapturedVar(VD);
3234 VInfo = std::make_pair(state->getLValue(VD, LocCtxt), VD->getType());
3236 SVal V = VInfo->first;
3237 bool IsReference = VInfo->second->isReferenceType();
3243 V = state->getSVal(R);
3248 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3252 if (
const auto *ED = dyn_cast<EnumConstantDecl>(D)) {
3254 SVal V = svalBuilder.makeIntVal(ED->getInitVal());
3258 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
3259 SVal V = svalBuilder.getFunctionPointer(FD);
3260 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3269 if (
const auto *BD = dyn_cast<BindingDecl>(D)) {
3271 if (std::optional<std::pair<SVal, QualType>> VInfo =
3272 resolveAsLambdaCapturedVar(BD)) {
3273 auto [
V,
T] = VInfo.value();
3275 if (
T->isReferenceType()) {
3277 V = state->getSVal(R);
3282 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3289 SVal Base = state->getLValue(DD, LCtx);
3290 if (DD->getType()->isReferenceType()) {
3292 Base = state->getSVal(R);
3300 if (
const auto *ME = dyn_cast<MemberExpr>(BD->getBinding())) {
3302 V = state->getLValue(Field,
Base);
3305 else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BD->getBinding())) {
3306 SVal Idx = state->getSVal(ASE->getIdx(), LCtx);
3311 assert(Idx.
isConstant() &&
"BindingDecl array index is not a constant!");
3313 V = state->getLValue(BD->getType(), Idx,
Base);
3316 else if (
const auto *HV = BD->getHoldingVar()) {
3317 V = state->getLValue(HV, LCtx);
3319 if (HV->getType()->isReferenceType()) {
3321 V = state->getSVal(R);
3326 llvm_unreachable(
"An unknown case of structured binding encountered!");
3330 if (BD->getType()->isReferenceType() && !BD->getHoldingVar()) {
3332 V = state->getSVal(R);
3337 Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3343 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(D)) {
3349 llvm_unreachable(
"Support for this Decl not implemented.");
3364 for (
auto *Node : CheckerPreStmt) {
3409 if (
const auto *ME = dyn_cast<MemberExpr>(Arr)) {
3410 Expr *MEBase = ME->getBase();
3413 if (
auto CXXSCE = dyn_cast<CXXStaticCastExpr>(MEBase)) {
3414 MEBase = CXXSCE->getSubExpr();
3435 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arr))
3440 Base = state->getSVal(R);
3469 (A->
getType().isCForbiddenLValueType() && !AMgr.getLangOpts().CPlusPlus);
3471 for (
auto *Node : CheckerPreStmt) {
3475 if (IsGLValueLike) {
3481 if (
T->isVoidType())
3484 SVal V = state->getLValue(
T,
3485 state->getSVal(Idx, LCtx),
3486 state->getSVal(
Base, LCtx));
3487 Bldr.
generateNode(A, Node, state->BindExpr(A, LCtx,
V),
nullptr,
3489 }
else if (IsVectorType) {
3493 llvm_unreachable(
"Array subscript should be an lValue when not \
3494a vector and not a forbidden lvalue type");
3514 for (
const auto I : CheckedSet)
3520 for (
const auto I : CheckedSet) {
3526 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
Member)) {
3527 if (MD->isImplicitObjectMemberFunction())
3528 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
3530 SVal MDVal = svalBuilder.getFunctionPointer(MD);
3531 state = state->BindExpr(M, LCtx, MDVal);
3539 state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr,
3546 if (
const auto *SR =
3547 dyn_cast_or_null<SymbolicRegion>(baseExprVal.
getAsRegion())) {
3548 QualType T = SR->getPointeeStaticType();
3554 SVal L = state->getLValue(field, baseExprVal);
3564 dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
3565 if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
3566 llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
3570 if (field->getType()->isReferenceType()) {
3572 L = state->getSVal(R);
3577 Bldr.
generateNode(M, I, state->BindExpr(M, LCtx, L),
nullptr,
3601 for (
const auto I : AfterPreSet) {
3606 for (
unsigned SI = 0, Count = AE->
getNumSubExprs(); SI != Count; SI++) {
3608 SVal SubExprVal = State->getSVal(SubExpr, LCtx);
3609 ValuesToInvalidate.push_back(SubExprVal);
3613 currBldrCtx->blockCount(), LCtx,
3618 State = State->BindExpr(AE, LCtx, ResultVal);
3638 for (
const std::pair<SVal, SVal> &LocAndVal : LocAndVals) {
3640 const MemRegion *MR = LocAndVal.first.getAsRegion();
3643 Escaped.push_back(LocAndVal.second);
3648 if (
const auto *VR = dyn_cast<VarRegion>(MR->
getBaseRegion()))
3650 VR->getStackFrame()->inTopFrame())
3651 if (
const auto *RD = VR->getValueType()->getAsCXXRecordDecl())
3652 if (!RD->hasTrivialDestructor()) {
3653 Escaped.push_back(LocAndVal.second);
3662 SVal StoredVal = State->getSVal(MR);
3663 if (StoredVal != LocAndVal.second)
3666 Escaped.push_back(LocAndVal.second);
3669 if (Escaped.empty())
3678 std::pair<SVal, SVal> LocAndVal(
Loc, Val);
3689 if (!Invalidated || Invalidated->empty())
3702 for (
const auto I : ExplicitRegions) {
3704 SymbolsDirectlyInvalidated.insert(R->getSymbol());
3708 for (
const auto &sym : *Invalidated) {
3709 if (SymbolsDirectlyInvalidated.count(sym))
3711 SymbolsIndirectlyInvalidated.insert(sym);
3714 if (!SymbolsDirectlyInvalidated.empty())
3719 if (!SymbolsIndirectlyInvalidated.empty())
3739 StoreE, AtDeclInit, *
this, *PP);
3750 Bldr.generateNode(L, state, Pred);
3754 for (
const auto PredI : CheckedSet) {
3762 state = state->bindLoc(location.
castAs<
Loc>(), Val, LC,
3766 if (std::optional<loc::MemRegionVal> LocRegVal =
3768 LocReg = LocRegVal->getRegion();
3772 Bldr.generateNode(L, state, PredI);
3785 const Expr *LocationE,
3791 const Expr *StoreE = AssignE ? AssignE : LocationE;
3795 evalLocation(Tmp, AssignE, LocationE, Pred, state, location,
false);
3803 for (
const auto I : Tmp)
3804 evalBind(Dst, StoreE, I, location, Val,
false);
3809 const Expr *BoundEx,
3815 assert(!
isa<NonLoc>(location) &&
"location cannot be a NonLoc.");
3820 evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location,
true);
3829 for (
const auto I : Tmp) {
3830 state = I->getState();
3837 V = state->getSVal(location.
castAs<
Loc>(), LoadTy);
3840 Bldr.
generateNode(NodeEx, I, state->BindExpr(BoundEx, LCtx,
V), tag,
3847 const Stmt *BoundEx,
3859 BldrTop.takeNodes(Pred);
3872 Bldr.generateNode(NodeEx, Pred, state, &tag);
3876 NodeEx, BoundEx, *
this);
3877 BldrTop.addNodes(Tmp);
3880std::pair<const ProgramPointTag *, const ProgramPointTag *>
3883 FalseTag(TagProviderName,
"Eagerly Assume False");
3885 return std::make_pair(&TrueTag, &FalseTag);
3909 State = State->set<LastEagerlyAssumeExprIfSuccessful>(
nullptr);
3912 if (SEV && SEV->isExpression()) {
3915 auto [StateTrue, StateFalse] = State->assume(*SEV);
3917 if (StateTrue && StateFalse) {
3918 StateTrue = StateTrue->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3919 StateFalse = StateFalse->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3940 const Expr *Ex)
const {
3941 return Ex && State->get<LastEagerlyAssumeExprIfSuccessful>() == Ex;
3960 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3962 currBldrCtx->blockCount(),
3971 if (std::optional<Loc> LV =
X.getAs<
Loc>())
3973 currBldrCtx->blockCount(),
4002 for (
const auto &
Report : Class.getReports()) {
4003 const auto *PR = dyn_cast<PathSensitiveBugReport>(
Report.get());
4021 llvm::function_ref<
void(
const ExplodedNode *)> PreCallback,
4022 llvm::function_ref<
void(
const ExplodedNode *)> PostCallback,
4044 llvm::raw_string_ostream Out(Buf);
4046 const bool IsDot =
true;
4047 const unsigned int Space = 1;
4050 Out <<
"{ \"state_id\": " << State->getID()
4053 Indent(Out, Space, IsDot) <<
"\"program_points\": [\\l";
4059 Indent(Out, Space + 1, IsDot) <<
"{ ";
4061 Out <<
", \"tag\": ";
4063 Out <<
'\"' << Tag->getDebugTag() <<
'\"';
4066 Out <<
", \"node_id\": " << OtherNode->
getID() <<
4067 ", \"is_sink\": " << OtherNode->
isSink() <<
4075 Indent(Out, Space, IsDot) <<
"],\\l";
4088 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
4092 std::string Filename =
DumpGraph(Nodes);
4093 llvm::DisplayGraph(Filename,
false, llvm::GraphProgram::DOT);
4098 std::vector<const ExplodedNode *> Src;
4101 for (
const auto &
Class : BR.equivalenceClasses()) {
4103 dyn_cast<PathSensitiveBugReport>(
Class.getReports()[0].get());
4106 const auto *N =
const_cast<ExplodedNode *
>(R->getErrorNode());
4112 return llvm::WriteGraph(&G,
"ExprEngine",
false,
4114 std::string(Filename));
4118 StringRef Filename) {
4119 std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
4122 llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
4126 return llvm::WriteGraph(TrimmedG.get(),
"TrimmedExprEngine",
4128 "Trimmed Exploded Graph",
4129 std::string(Filename));
4133 static int index = 0;
4137void ExprEngine::anchor() { }
4150 bool IsCompound =
T->isArrayType() ||
T->isRecordType() ||
4151 T->isAnyComplexType() ||
T->isVectorType();
4153 if (Args.size() > 1 || (E->
isPRValue() && IsCompound && !IsTransparent)) {
4155 for (
Expr *E : llvm::reverse(Args))
4159 S->BindExpr(E, LC, svalBuilder.makeCompoundVal(
T, ArgList)));
4165 : 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.
CFGTerminator getTerminator() const
Stmt * getTerminatorStmt()
unsigned getBlockID() 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 * 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.
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
@ 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 Stmt * 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.
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 isEnumeralType() 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 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 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 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.
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.
BasicValueFactory & getBasicVals()
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 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.
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.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
StoreManager & getStoreManager()
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
BugReporter & getBugReporter()
void processCFGBlockEntrance(const BlockEdge &L, NodeBuilderWithSinks &nodeBuilder, ExplodedNode *Pred)
Called by CoreEngine when processing the entrance of a CFGBlock.
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 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 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 processBranch(const Stmt *Condition, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF, std::optional< unsigned > IterationsCompletedInLoop)
ProcessBranch - Called by CoreEngine.
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
SymbolManager & getSymbolManager()
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 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()
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 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.
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
AnalysisManager & getAnalysisManager()
ExplodedGraph & getGraph()
void runCheckersForBlockEntrance(const NodeBuilderContext &BldCtx, const BlockEntrance &Entrance, ExplodedNode *Pred, ExplodedNodeSet &Dst)
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 VisitAttributedStmt(const AttributedStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAttributedStmt - Transfer function logic for AttributedStmt.
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, ExplodedNodeSet &PreVisit, ExplodedNodeSet &Dst)
void processIndirectGoto(IndirectGotoNodeBuilder &builder)
processIndirectGoto - Called by CoreEngine.
const NodeBuilderContext & getBuilderContext()
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 ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
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)
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...
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.
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.
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.
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.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
@ CXXThis
Parameter for C++ 'this' argument.
Diagnostic wrappers for TextAPI types for error reporting.
Describes how types, statements, expressions, and declarations should be printed.
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
Hints for figuring out 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)