;
90#define DEBUG_TYPE "ExprEngine" 93 "The # of times RemoveDeadBindings is called");
95 "The # of aborted paths due to reaching the maximum block count in " 96 "a top level function");
98 "The # of aborted paths due to reaching the maximum block count in " 99 "an inlined function");
101 "The # of times we re-evaluated a call without inlining");
122classConstructedObjectKey {
123 usingConstructedObjectKeyImpl =
124std::pair<ConstructionContextItem, const LocationContext *>;
125 constConstructedObjectKeyImpl Impl;
133 const LocationContext*getLocationContext()
const{
returnImpl.second; }
136 returngetLocationContext()->getDecl()->getASTContext();
139 voidprintJson(llvm::raw_ostream &Out,
PrinterHelper*Helper,
141 const Stmt*S = getItem().getStmtOrNull();
144I = getItem().getCXXCtorInitializer();
147Out <<
"\"stmt_id\": "<< S->getID(getASTContext());
149Out <<
"\"init_id\": "<< I->
getID(getASTContext());
152Out <<
", \"kind\": \""<< getItem().getKindAsString()
153<<
"\", \"argument_index\": ";
156Out << getItem().getIndex();
161Out <<
", \"pretty\": ";
164S->printJson(Out, Helper, PP,
true);
170 voidProfile(llvm::FoldingSetNodeID &ID)
const{
172 ID.AddPointer(Impl.second);
175 bool operator==(
constConstructedObjectKey &RHS)
const{
176 returnImpl == RHS.Impl;
179 bool operator<(
constConstructedObjectKey &RHS)
const{
180 returnImpl < RHS.Impl;
185typedefllvm::ImmutableMap<ConstructedObjectKey, SVal>
196typedefllvm::ImmutableMap<
197std::pair<const CXXConstructExpr *, const LocationContext *>,
unsigned>
198IndexOfElementToConstructMap;
200IndexOfElementToConstructMap)
205typedefllvm::ImmutableMap<
206std::pair<const CXXConstructExpr *, const LocationContext *>,
unsigned>
210typedefllvm::ImmutableMap<const LocationContext *, unsigned>
219static const char* TagProviderName =
"ExprEngine";
224: CTU(CTU), IsCTUEnabled(mgr.getAnalyzerOptions().IsNaiveCTUEnabled),
225AMgr(mgr), AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
226Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.getGraph()),
227StateMgr(getContext(), mgr.getStoreManagerCreator(),
228mgr.getConstraintManagerCreator(), G.getAllocator(), this),
229SymMgr(StateMgr.getSymbolManager()), MRMgr(StateMgr.getRegionManager()),
230svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()),
231BR(mgr, *this), VisitedCallees(VisitedCalleesIn),
232HowToInline(HowToInlineIn) {
233 unsignedTrimInterval = mgr.
options.GraphTrimInterval;
234 if(TrimInterval != 0) {
252 if(
const auto*FD = dyn_cast<FunctionDecl>(
D)) {
256 if(!II || !(II->
getName() ==
"main"&& FD->getNumParams() > 0))
261 const auto*BT = dyn_cast<BuiltinType>(
T);
262 if(!BT || !BT->isInteger())
265 const MemRegion*R = state->getRegion(PD, InitLoc);
274std::optional<DefinedOrUnknownSVal> Constraint =
287 if(
const auto*MD = dyn_cast<ObjCMethodDecl>(
D)) {
291 const MemRegion*R = state->getRegion(SelfD, InitLoc);
294 if(std::optional<Loc> LV =
V.getAs<
Loc>()) {
296state = state->assume(*LV,
true);
297assert(state &&
"'self' cannot be null");
301 if(
const auto*MD = dyn_cast<CXXMethodDecl>(
D)) {
302 if(MD->isImplicitObjectMemberFunction()) {
309 SVal V= state->getSVal(L);
310 if(std::optional<Loc> LV =
V.getAs<
Loc>()) {
311state = state->assume(*LV,
true);
312assert(state &&
"'this' cannot be null");
324 const SubRegion**OutRegionWithAdjustments) {
330 SValInitValWithAdjustments = State->getSVal(InitWithAdjustments, LC);
334 if(!isa<NonLoc>(InitValWithAdjustments)) {
335 if(OutRegionWithAdjustments)
336*OutRegionWithAdjustments =
nullptr;
339 Result= InitWithAdjustments;
343assert(!isa<Loc>(InitValWithAdjustments) ||
345 Result->getType()->isMemberPointerType());
377CommaLHSs, Adjustments);
385 if(
const auto*MT = dyn_cast<MaterializeTemporaryExpr>(
Result)) {
387State = finishObjectConstruction(State, MT, LC);
388State = State->BindExpr(
Result, LC, *
V);
390}
else if(
const ValueDecl*VD = MT->getExtendingDecl()) {
422State = State->invalidateRegions(Reg, InitWithAdjustments,
424 nullptr,
nullptr,
nullptr);
437 SValInitVal = State->getSVal(
Init, LC);
441State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
445 if(InitValWithAdjustments.
isUnknown()) {
453State->bindLoc(Reg.
castAs<
Loc>(), InitValWithAdjustments, LC,
false);
455State = State->bindLoc(BaseReg.
castAs<
Loc>(), InitVal, LC,
false);
461 if(
Result->isGLValue()) {
462State = State->BindExpr(
Result, LC, Reg);
464State = State->BindExpr(
Result, LC, InitValWithAdjustments);
470 if(OutRegionWithAdjustments)
471*OutRegionWithAdjustments = cast<SubRegion>(Reg.
getAsRegion());
480assert(!State->contains<IndexOfElementToConstruct>(Key) || Idx > 0);
482 returnState->set<IndexOfElementToConstruct>(Key, Idx);
485std::optional<unsigned>
488 const unsigned*
V= State->get<PendingInitLoop>({
E, LCtx->
getStackFrame()});
489 return V? std::make_optional(*
V) : std::nullopt;
497assert(
E&& State->contains<PendingInitLoop>(Key));
498 returnState->remove<PendingInitLoop>(Key);
507assert(!State->contains<PendingInitLoop>(Key) && Size > 0);
509 returnState->set<PendingInitLoop>(Key, Size);
512std::optional<unsigned>
517State->get<IndexOfElementToConstruct>({
E, LCtx->
getStackFrame()});
518 return V? std::make_optional(*
V) : std::nullopt;
527assert(
E&& State->contains<IndexOfElementToConstruct>(Key));
528 returnState->remove<IndexOfElementToConstruct>(Key);
531std::optional<unsigned>
534assert(LCtx &&
"LocationContext shouldn't be null!");
537State->get<PendingArrayDestruction>(LCtx->
getStackFrame());
538 return V? std::make_optional(*
V) : std::nullopt;
543assert(LCtx &&
"LocationContext shouldn't be null!");
547 returnState->set<PendingArrayDestruction>(Key, Idx);
553assert(LCtx &&
"LocationContext shouldn't be null!");
557assert(LCtx && State->contains<PendingArrayDestruction>(Key));
558 returnState->remove<PendingArrayDestruction>(Key);
569 if(
autoDS = dyn_cast_or_null<DeclStmt>(Item.
getStmtOrNull())) {
570 if(
autoVD = dyn_cast_or_null<VarDecl>(DS->getSingleDecl()))
571 Init= VD->getInit();
574 if(
autoLE = dyn_cast_or_null<LambdaExpr>(Item.
getStmtOrNull()))
583 if(
const auto*AILE = dyn_cast_or_null<ArrayInitLoopExpr>(
Init))
592assert((!State->get<ObjectsUnderConstruction>(Key) ||
593Key.getItem().getKind() ==
595State->contains<IndexOfElementToConstruct>(
596{dyn_cast_or_null<CXXConstructExpr>(Init), LC})) &&
597 "The object is already marked as `UnderConstruction`, when it's not " 599 returnState->set<ObjectsUnderConstruction>(Key,
V);
607 const SVal*
V= State->get<ObjectsUnderConstruction>(Key);
608 return V? std::make_optional(*
V) : std::nullopt;
616assert(State->contains<ObjectsUnderConstruction>(Key));
617 returnState->remove<ObjectsUnderConstruction>(Key);
623ConstructedObjectKey Key({BTE,
true}, LC);
626 returnState->set<ObjectsUnderConstruction>(Key,
UnknownVal());
633ConstructedObjectKey Key({BTE,
true}, LC);
634assert(State->contains<ObjectsUnderConstruction>(Key));
635 returnState->remove<ObjectsUnderConstruction>(Key);
641ConstructedObjectKey Key({BTE,
true}, LC);
642 returnState->contains<ObjectsUnderConstruction>(Key);
650assert(LC &&
"ToLC must be a parent of FromLC!");
651 for(
autoI : State->get<ObjectsUnderConstruction>())
652 if(I.first.getLocationContext() == LC)
668 SValcond,
boolassumption) {
687 unsigned intSpace = 0,
boolIsDot =
false) {
692 boolHasItem =
false;
695 constConstructedObjectKey *LastKey =
nullptr;
696 for(
const auto&I : State->get<ObjectsUnderConstruction>()) {
697 constConstructedObjectKey &Key = I.first;
698 if(Key.getLocationContext() != LCtx)
709 for(
const auto&I : State->get<ObjectsUnderConstruction>()) {
710 constConstructedObjectKey &Key = I.first;
712 if(Key.getLocationContext() != LCtx)
715Indent(Out, Space, IsDot) <<
"{ ";
716Key.printJson(Out,
nullptr, PP);
717Out <<
", \"value\": \""<<
Value<<
"\" }";
725Indent(Out, --Space, IsDot) <<
']';
733 const LocationContext*LCtx,
unsigned intSpace = 0,
boolIsDot =
false) {
734 usingKeyT = std::pair<const Expr *, const LocationContext *>;
740 boolHasItem =
false;
744 for(
const auto&I : State->get<IndexOfElementToConstruct>()) {
745 constKeyT &Key = I.first;
746 if(Key.second != LCtx)
757 for(
const auto&I : State->get<IndexOfElementToConstruct>()) {
758 constKeyT &Key = I.first;
759 unsigned Value= I.second;
760 if(Key.second != LCtx)
763Indent(Out, Space, IsDot) <<
"{ ";
766 const Expr*
E= Key.first;
767Out <<
"\"stmt_id\": "<<
E->
getID(Context);
770Out <<
", \"kind\": null";
773Out <<
", \"pretty\": ";
779Out <<
", \"value\": \"Current index: "<<
Value- 1 <<
"\" }";
787Indent(Out, --Space, IsDot) <<
']';
796 unsigned intSpace = 0,
797 boolIsDot =
false) {
798 usingKeyT = std::pair<const CXXConstructExpr *, const LocationContext *>;
804 boolHasItem =
false;
808 for(
const auto&I : State->get<PendingInitLoop>()) {
809 constKeyT &Key = I.first;
810 if(Key.second != LCtx)
821 for(
const auto&I : State->get<PendingInitLoop>()) {
822 constKeyT &Key = I.first;
823 unsigned Value= I.second;
824 if(Key.second != LCtx)
827Indent(Out, Space, IsDot) <<
"{ ";
830Out <<
"\"stmt_id\": "<<
E->
getID(Context);
832Out <<
", \"kind\": null";
833Out <<
", \"pretty\": ";
839Out <<
", \"value\": \"Flattened size: "<<
Value<<
"\"}";
847Indent(Out, --Space, IsDot) <<
']';
856 unsigned intSpace = 0,
boolIsDot =
false) {
860 boolHasItem =
false;
863KeyT LastKey =
nullptr;
864 for(
const auto&I : State->get<PendingArrayDestruction>()) {
865 constKeyT &Key = I.first;
877 for(
const auto&I : State->get<PendingArrayDestruction>()) {
878 constKeyT &Key = I.first;
882Indent(Out, Space, IsDot) <<
"{ ";
884Out <<
"\"stmt_id\": null";
885Out <<
", \"kind\": null";
886Out <<
", \"pretty\": \"Current index: \"";
887Out <<
", \"value\": \""<< I.second <<
"\" }";
895Indent(Out, --Space, IsDot) <<
']';
909template<
typenameTrait,
typenamePrinter,
typename... Args>
912 const char*NL,
unsigned intSpace,
boolIsDot,
913 const char*jsonPropertyName, Printer printer, Args &&...args) {
921 static_assert(std::is_function_v<std::remove_pointer_t<Printer>>,
922 "Printer is not a function!");
923 static_assert(std::is_convertible_v<Printer, RequiredType>,
924 "Printer doesn't have the required type!");
926 if(LCtx && !State->get<Trait>().isEmpty()) {
927Indent(Out, Space, IsDot) <<
'\"'<< jsonPropertyName <<
"\": ";
931printer(Out, State, NL, LC, Space, IsDot, std::forward<Args>(args)...);
935Indent(Out, Space, IsDot) <<
"],"<< NL;
941 unsigned intSpace,
boolIsDot)
const{
943printStateTraitWithLocationContextJson<ObjectsUnderConstruction>(
944Out, State, LCtx, NL, Space, IsDot,
"constructing_objects",
946printStateTraitWithLocationContextJson<IndexOfElementToConstruct>(
947Out, State, LCtx, NL, Space, IsDot,
"index_of_element",
949printStateTraitWithLocationContextJson<PendingInitLoop>(
950Out, State, LCtx, NL, Space, IsDot,
"pending_init_loops",
952printStateTraitWithLocationContextJson<PendingArrayDestruction>(
953Out, State, LCtx, NL, Space, IsDot,
"pending_destructors",
969currStmtIdx = StmtIdx;
972 switch(
E.getKind()) {
1030 const Stmt*ReferenceStmt,
1032 const Stmt*DiagnosticStmt,
1035ReferenceStmt ==
nullptr|| isa<ReturnStmt>(ReferenceStmt))
1036&&
"PostStmt is not generally supported by the SymbolReaper yet");
1037assert(LC &&
"Must pass the current (or expiring) LocationContext");
1039 if(!DiagnosticStmt) {
1040DiagnosticStmt = ReferenceStmt;
1041assert(DiagnosticStmt &&
"Required for clearing a LocationContext");
1044NumRemoveDeadBindings++;
1050 if(!ReferenceStmt) {
1052 "Use PostStmtPurgeDeadSymbolsKind for clearing a LocationContext");
1059 for(
autoI : CleanedState->get<ObjectsUnderConstruction>()) {
1060 if(
SymbolRefSym = I.second.getAsSymbol())
1062 if(
const MemRegion*MR = I.second.getAsRegion())
1072CleanedState, SFC, SymReaper);
1079DiagnosticStmt, *
this, K);
1085 for(
const autoI : CheckedSet) {
1093 "Checkers are not allowed to modify the Environment as a part of " 1094 "checkDeadSymbols processing.");
1096 "Checkers are not allowed to modify the Store as a part of " 1097 "checkDeadSymbols processing.");
1118 "Error evaluating statement");
1127CleanedStates.
Add(Pred);
1131 for(
const autoI : CleanedStates) {
1134 Visit(currStmt, I, DstI);
1145 "Error evaluating end of the loop");
1151 if(AMgr.
options.ShouldUnrollLoops)
1168 "Error evaluating initializer");
1172 const auto*
decl= cast<CXXConstructorDecl>(stackFrame->getDecl());
1187State = finishObjectConstruction(State, BMI, LC);
1198FieldLoc = State->getLValue(BMI->
getMember(), thisVal);
1202 if(
Init->getType()->isArrayType()) {
1206 while((ASE = dyn_cast<ArraySubscriptExpr>(
Init)))
1209InitVal = State->getSVal(
Init, stackFrame);
1219InitVal = State->getSVal(BMI->
getInit(), stackFrame);
1223evalBind(Tmp,
Init, Pred, FieldLoc, InitVal,
true, &PP);
1231 SValInitVal = State->getSVal(
Init, stackFrame);
1232evalBind(Tmp,
Init, Pred, BaseLoc, InitVal,
true);
1244 for(
const autoI : Tmp) {
1253std::pair<ProgramStateRef, uint64_t>
1254ExprEngine::prepareStateForArrayDestruction(
const ProgramStateRefState,
1258 SVal*ElementCountVal) {
1259assert(Region !=
nullptr&&
"Not-null region expected");
1262 while(
const auto*NTy = dyn_cast<ArrayType>(Ty))
1263Ty = NTy->getElementType().getDesugaredType(
getContext());
1267 if(ElementCountVal)
1268*ElementCountVal = ElementCount;
1276 if(!ElementCount.isConstant())
1279Idx = ElementCount.getAsInteger()->getLimitedValue();
1287 return{setPendingArrayDestruction(State, LCtx, Idx), Idx};
1310llvm_unreachable(
"Unexpected dtor kind.");
1325 if(Opts.MayInlineCXXAllocator)
1351 const MemRegion*ValueRegion = state->getSVal(Region).getAsRegion();
1360varType = cast<TypedValueRegion>(Region)->getValueType();
1364 if(isa<ArrayType>(varType)) {
1366std::tie(state, Idx) = prepareStateForArrayDestruction(
1367state, Region, varType, LCtx, &ElementCount);
1370uint64_t ArrayLength = ElementCount.
getAsInteger()->getLimitedValue();
1371assert(ArrayLength &&
1372 "An automatic dtor for a 0 length array shouldn't be triggered!");
1377 "ExprEngine",
"Skipping automatic 0 length array destruction, " 1378 "which shouldn't be in the CFG.");
1396 "Prepare for object destruction");
1406 false, Pred, Dst, CallOpts);
1417 SValArgVal = State->getSVal(Arg, LCtx);
1421 if(State->isNull(ArgVal).isConstrainedTrue()) {
1432 autogetDtorDecl = [](
const QualType&DTy) {
1445DTy = AT->getElementType();
1449std::tie(State, Idx) = prepareStateForArrayDestruction(
1450State, ArgR, DTy, LCtx, &ElementCount);
1455ElementCount.
getAsInteger()->getLimitedValue() == 0) {
1458 "ExprEngine",
"Skipping 0 length array delete destruction");
1466ArgR = State->getLValue(DTy, svalBuilder.
makeArrayIndex(Idx), ArgVal)
1473 "Prepare for object destruction");
1489 const auto*CurDtor = cast<CXXDestructorDecl>(LCtx->
getDecl());
1498 Base->isVirtual());
1502 true, Pred, Dst, CallOpts);
1507 const auto*DtorDecl =
D.getDestructorDecl(
getContext());
1513 const auto*CurDtor = cast<CXXDestructorDecl>(LCtx->
getDecl());
1514 LocThisStorageLoc =
1516 LocThisLoc = State->getSVal(ThisStorageLoc).castAs<
Loc>();
1517 SValFieldVal = State->getLValue(
Member, ThisLoc);
1520 if(isa<ArrayType>(
T)) {
1522std::tie(State, Idx) = prepareStateForArrayDestruction(
1523State, FieldVal.getAsRegion(),
T, LCtx, &ElementCount);
1526uint64_t ArrayLength = ElementCount.
getAsInteger()->getLimitedValue();
1527assert(ArrayLength &&
1528 "A member dtor for a 0 length array shouldn't be triggered!");
1533 "ExprEngine",
"Skipping member 0 length array destruction, which " 1534 "shouldn't be in the CFG.");
1551 "Prepare for object destruction");
1561 false, Pred, Dst, CallOpts);
1577State = finishObjectConstruction(State,
D.getBindTemporaryExpr(),
1579MR =
V->getAsRegion();
1584 if(isDestructorElided(State, BTE, LC)) {
1585State = cleanupElidedDestructor(State, BTE, LC);
1596StmtBldr.
generateNode(
D.getBindTemporaryExpr(), Pred, State);
1598 QualType T=
D.getBindTemporaryExpr()->getSubExpr()->getType();
1601assert(CleanDtorState.
size() <= 1);
1603CleanDtorState.
empty() ? Pred : *CleanDtorState.
begin();
1626 T= AT->getElementType();
1637 false, CleanPred, Dst, CallOpts);
1677State = addObjectUnderConstruction(State, BTE, LC,
UnknownVal());
1687 classCollectReachableSymbolsCallback final :
public SymbolVisitor{
1692: Symbols(Symbols) {}
1696 boolVisitSymbol(
SymbolRefSym)
override{
1697Symbols.insert(Sym);
1702CollectReachableSymbolsCallback CallBack(Symbols);
1704State->scanReachableSymbols(
V, CallBack);
1707State, CallBack.getSymbols(),
Call, K,
nullptr);
1713S->getBeginLoc(),
"Error evaluating statement");
1717assert(!isa<Expr>(S) || S == cast<Expr>(S)->IgnoreParens());
1719 switch(S->getStmtClass()) {
1721 caseStmt::CXXDependentScopeMemberExprClass:
1722 caseStmt::CXXTryStmtClass:
1723 caseStmt::CXXTypeidExprClass:
1724 caseStmt::CXXUuidofExprClass:
1725 caseStmt::CXXFoldExprClass:
1726 caseStmt::MSPropertyRefExprClass:
1727 caseStmt::MSPropertySubscriptExprClass:
1728 caseStmt::CXXUnresolvedConstructExprClass:
1729 caseStmt::DependentScopeDeclRefExprClass:
1730 caseStmt::ArrayTypeTraitExprClass:
1731 caseStmt::ExpressionTraitExprClass:
1732 caseStmt::UnresolvedLookupExprClass:
1733 caseStmt::UnresolvedMemberExprClass:
1734 caseStmt::TypoExprClass:
1735 caseStmt::RecoveryExprClass:
1736 caseStmt::CXXNoexceptExprClass:
1737 caseStmt::PackExpansionExprClass:
1738 caseStmt::PackIndexingExprClass:
1739 caseStmt::SubstNonTypeTemplateParmPackExprClass:
1740 caseStmt::FunctionParmPackExprClass:
1741 caseStmt::CoroutineBodyStmtClass:
1742 caseStmt::CoawaitExprClass:
1743 caseStmt::DependentCoawaitExprClass:
1744 caseStmt::CoreturnStmtClass:
1745 caseStmt::CoyieldExprClass:
1746 caseStmt::ResolvedUnexpandedPackExprClass:
1747 caseStmt::SEHTryStmtClass:
1748 caseStmt::SEHExceptStmtClass:
1749 caseStmt::SEHLeaveStmtClass:
1750 caseStmt::SEHFinallyStmtClass:
1751 caseStmt::OMPCanonicalLoopClass:
1752 caseStmt::OMPParallelDirectiveClass:
1753 caseStmt::OMPSimdDirectiveClass:
1754 caseStmt::OMPForDirectiveClass:
1755 caseStmt::OMPForSimdDirectiveClass:
1756 caseStmt::OMPSectionsDirectiveClass:
1757 caseStmt::OMPSectionDirectiveClass:
1758 caseStmt::OMPScopeDirectiveClass:
1759 caseStmt::OMPSingleDirectiveClass:
1760 caseStmt::OMPMasterDirectiveClass:
1761 caseStmt::OMPCriticalDirectiveClass:
1762 caseStmt::OMPParallelForDirectiveClass:
1763 caseStmt::OMPParallelForSimdDirectiveClass:
1764 caseStmt::OMPParallelSectionsDirectiveClass:
1765 caseStmt::OMPParallelMasterDirectiveClass:
1766 caseStmt::OMPParallelMaskedDirectiveClass:
1767 caseStmt::OMPTaskDirectiveClass:
1768 caseStmt::OMPTaskyieldDirectiveClass:
1769 caseStmt::OMPBarrierDirectiveClass:
1770 caseStmt::OMPTaskwaitDirectiveClass:
1771 caseStmt::OMPErrorDirectiveClass:
1772 caseStmt::OMPTaskgroupDirectiveClass:
1773 caseStmt::OMPFlushDirectiveClass:
1774 caseStmt::OMPDepobjDirectiveClass:
1775 caseStmt::OMPScanDirectiveClass:
1776 caseStmt::OMPOrderedDirectiveClass:
1777 caseStmt::OMPAtomicDirectiveClass:
1778 caseStmt::OMPAssumeDirectiveClass:
1779 caseStmt::OMPTargetDirectiveClass:
1780 caseStmt::OMPTargetDataDirectiveClass:
1781 caseStmt::OMPTargetEnterDataDirectiveClass:
1782 caseStmt::OMPTargetExitDataDirectiveClass:
1783 caseStmt::OMPTargetParallelDirectiveClass:
1784 caseStmt::OMPTargetParallelForDirectiveClass:
1785 caseStmt::OMPTargetUpdateDirectiveClass:
1786 caseStmt::OMPTeamsDirectiveClass:
1787 caseStmt::OMPCancellationPointDirectiveClass:
1788 caseStmt::OMPCancelDirectiveClass:
1789 caseStmt::OMPTaskLoopDirectiveClass:
1790 caseStmt::OMPTaskLoopSimdDirectiveClass:
1791 caseStmt::OMPMasterTaskLoopDirectiveClass:
1792 caseStmt::OMPMaskedTaskLoopDirectiveClass:
1793 caseStmt::OMPMasterTaskLoopSimdDirectiveClass:
1794 caseStmt::OMPMaskedTaskLoopSimdDirectiveClass:
1795 caseStmt::OMPParallelMasterTaskLoopDirectiveClass:
1796 caseStmt::OMPParallelMaskedTaskLoopDirectiveClass:
1797 caseStmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1798 caseStmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
1799 caseStmt::OMPDistributeDirectiveClass:
1800 caseStmt::OMPDistributeParallelForDirectiveClass:
1801 caseStmt::OMPDistributeParallelForSimdDirectiveClass:
1802 caseStmt::OMPDistributeSimdDirectiveClass:
1803 caseStmt::OMPTargetParallelForSimdDirectiveClass:
1804 caseStmt::OMPTargetSimdDirectiveClass:
1805 caseStmt::OMPTeamsDistributeDirectiveClass:
1806 caseStmt::OMPTeamsDistributeSimdDirectiveClass:
1807 caseStmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1808 caseStmt::OMPTeamsDistributeParallelForDirectiveClass:
1809 caseStmt::OMPTargetTeamsDirectiveClass:
1810 caseStmt::OMPTargetTeamsDistributeDirectiveClass:
1811 caseStmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1812 caseStmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1813 caseStmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1814 caseStmt::OMPReverseDirectiveClass:
1815 caseStmt::OMPTileDirectiveClass:
1816 caseStmt::OMPInterchangeDirectiveClass:
1817 caseStmt::OMPInteropDirectiveClass:
1818 caseStmt::OMPDispatchDirectiveClass:
1819 caseStmt::OMPMaskedDirectiveClass:
1820 caseStmt::OMPGenericLoopDirectiveClass:
1821 caseStmt::OMPTeamsGenericLoopDirectiveClass:
1822 caseStmt::OMPTargetTeamsGenericLoopDirectiveClass:
1823 caseStmt::OMPParallelGenericLoopDirectiveClass:
1824 caseStmt::OMPTargetParallelGenericLoopDirectiveClass:
1825 caseStmt::CapturedStmtClass:
1826 caseStmt::SYCLKernelCallStmtClass:
1827 caseStmt::OpenACCComputeConstructClass:
1828 caseStmt::OpenACCLoopConstructClass:
1829 caseStmt::OpenACCCombinedConstructClass:
1830 caseStmt::OpenACCDataConstructClass:
1831 caseStmt::OpenACCEnterDataConstructClass:
1832 caseStmt::OpenACCExitDataConstructClass:
1833 caseStmt::OpenACCHostDataConstructClass:
1834 caseStmt::OpenACCWaitConstructClass:
1835 caseStmt::OpenACCInitConstructClass:
1836 caseStmt::OpenACCShutdownConstructClass:
1837 caseStmt::OpenACCSetConstructClass:
1838 caseStmt::OpenACCUpdateConstructClass:
1839 caseStmt::OMPUnrollDirectiveClass:
1840 caseStmt::OMPMetaDirectiveClass:
1841 caseStmt::HLSLOutArgExprClass: {
1847 caseStmt::ParenExprClass:
1848llvm_unreachable(
"ParenExprs already handled.");
1849 caseStmt::GenericSelectionExprClass:
1850llvm_unreachable(
"GenericSelectionExprs already handled.");
1853 caseStmt::BreakStmtClass:
1854 caseStmt::CaseStmtClass:
1855 caseStmt::CompoundStmtClass:
1856 caseStmt::ContinueStmtClass:
1857 caseStmt::CXXForRangeStmtClass:
1858 caseStmt::DefaultStmtClass:
1859 caseStmt::DoStmtClass:
1860 caseStmt::ForStmtClass:
1861 caseStmt::GotoStmtClass:
1862 caseStmt::IfStmtClass:
1863 caseStmt::IndirectGotoStmtClass:
1864 caseStmt::LabelStmtClass:
1866 caseStmt::NullStmtClass:
1867 caseStmt::SwitchStmtClass:
1868 caseStmt::WhileStmtClass:
1869 caseExpr::MSDependentExistsStmtClass:
1870llvm_unreachable(
"Stmt should not be in analyzer evaluation loop");
1871 caseStmt::ImplicitValueInitExprClass:
1875llvm_unreachable(
"Should be pruned from CFG");
1877 caseStmt::ObjCSubscriptRefExprClass:
1878 caseStmt::ObjCPropertyRefExprClass:
1879llvm_unreachable(
"These are handled by PseudoObjectExpr");
1881 caseStmt::GNUNullExprClass: {
1884state = state->BindExpr(
1891 caseStmt::ObjCAtSynchronizedStmtClass:
1897 caseExpr::ConstantExprClass:
1898 caseStmt::ExprWithCleanupsClass:
1902 caseStmt::CXXBindTemporaryExprClass: {
1913 caseStmt::ArrayInitLoopExprClass:
1919 caseStmt::DesignatedInitExprClass:
1920 caseStmt::DesignatedInitUpdateExprClass:
1921 caseStmt::ArrayInitIndexExprClass:
1922 caseStmt::ExtVectorElementExprClass:
1923 caseStmt::ImaginaryLiteralClass:
1924 caseStmt::ObjCAtCatchStmtClass:
1925 caseStmt::ObjCAtFinallyStmtClass:
1926 caseStmt::ObjCAtTryStmtClass:
1927 caseStmt::ObjCAutoreleasePoolStmtClass:
1928 caseStmt::ObjCEncodeExprClass:
1929 caseStmt::ObjCIsaExprClass:
1930 caseStmt::ObjCProtocolExprClass:
1931 caseStmt::ObjCSelectorExprClass:
1932 caseStmt::ParenListExprClass:
1933 caseStmt::ShuffleVectorExprClass:
1934 caseStmt::ConvertVectorExprClass:
1935 caseStmt::VAArgExprClass:
1936 caseStmt::CUDAKernelCallExprClass:
1937 caseStmt::OpaqueValueExprClass:
1938 caseStmt::AsTypeExprClass:
1939 caseStmt::ConceptSpecializationExprClass:
1940 caseStmt::CXXRewrittenBinaryOperatorClass:
1941 caseStmt::RequiresExprClass:
1942 caseExpr::CXXParenListInitExprClass:
1943 caseStmt::EmbedExprClass:
1948 caseStmt::PredefinedExprClass:
1949 caseStmt::AddrLabelExprClass:
1950 caseStmt::AttributedStmtClass:
1951 caseStmt::IntegerLiteralClass:
1952 caseStmt::FixedPointLiteralClass:
1953 caseStmt::CharacterLiteralClass:
1954 caseStmt::CXXScalarValueInitExprClass:
1955 caseStmt::CXXBoolLiteralExprClass:
1956 caseStmt::ObjCBoolLiteralExprClass:
1957 caseStmt::ObjCAvailabilityCheckExprClass:
1958 caseStmt::FloatingLiteralClass:
1959 caseStmt::NoInitExprClass:
1960 caseStmt::SizeOfPackExprClass:
1961 caseStmt::StringLiteralClass:
1962 caseStmt::SourceLocExprClass:
1963 caseStmt::ObjCStringLiteralClass:
1964 caseStmt::CXXPseudoDestructorExprClass:
1965 caseStmt::SubstNonTypeTemplateParmExprClass:
1966 caseStmt::CXXNullPtrLiteralExprClass:
1967 caseStmt::ArraySectionExprClass:
1968 caseStmt::OMPArrayShapingExprClass:
1969 caseStmt::OMPIteratorExprClass:
1970 caseStmt::SYCLUniqueStableNameExprClass:
1971 caseStmt::OpenACCAsteriskSizeExprClass:
1972 caseStmt::TypeTraitExprClass: {
1981 caseStmt::CXXDefaultArgExprClass:
1982 caseStmt::CXXDefaultInitExprClass: {
1991 if(
const auto*DefE = dyn_cast<CXXDefaultArgExpr>(S))
1992ArgE = DefE->getExpr();
1993 else if(
const auto*DefE = dyn_cast<CXXDefaultInitExpr>(S))
1994ArgE = DefE->getExpr();
1996llvm_unreachable(
"unknown constant wrapper kind");
1998 boolIsTemporary =
false;
1999 if(
const auto*MTE = dyn_cast<MaterializeTemporaryExpr>(ArgE)) {
2000ArgE = MTE->getSubExpr();
2001IsTemporary =
true;
2004std::optional<SVal> ConstantVal = svalBuilder.
getConstantVal(ArgE);
2009 for(
const autoI : PreVisit) {
2011State = State->BindExpr(S, LCtx, *ConstantVal);
2013State = createTemporaryRegionIfNeeded(State, LCtx,
2025 caseStmt::CXXStdInitializerListExprClass:
2026 caseExpr::ObjCArrayLiteralClass:
2027 caseExpr::ObjCDictionaryLiteralClass:
2028 caseExpr::ObjCBoxedExprClass: {
2037 const auto*Ex = cast<Expr>(S);
2038 QualTyperesultType = Ex->getType();
2040 for(
const autoN : preVisit) {
2049 if(!(isa<ObjCBoxedExpr>(Ex) &&
2050!cast<ObjCBoxedExpr>(Ex)->getSubExpr()
2052 for(
autoChild : Ex->children()) {
2054 SValVal = State->getSVal(Child, LCtx);
2066 caseStmt::ArraySubscriptExprClass:
2072 caseStmt::MatrixSubscriptExprClass:
2073llvm_unreachable(
"Support for MatrixSubscriptExpr is not implemented.");
2076 caseStmt::GCCAsmStmtClass: {
2088 caseStmt::MSAsmStmtClass:
2094 caseStmt::BlockExprClass:
2100 caseStmt::LambdaExprClass:
2101 if(AMgr.
options.ShouldInlineLambdas) {
2111 caseStmt::BinaryOperatorClass: {
2112 const auto*B = cast<BinaryOperator>(S);
2113 if(B->isLogicalOp()) {
2119 else if(B->getOpcode() == BO_Comma) {
2123state->getSVal(B->getRHS(),
2130 if(AMgr.
options.ShouldEagerlyAssume &&
2131(B->isRelationalOp() || B->isEqualityOp())) {
2143 caseStmt::CXXOperatorCallExprClass: {
2144 const auto*OCE = cast<CXXOperatorCallExpr>(S);
2148 const Decl*Callee = OCE->getCalleeDecl();
2149 if(
const auto*MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
2150 if(MD->isImplicitObjectMemberFunction()) {
2154createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
2155 if(NewState != State) {
2156Pred = Bldr.
generateNode(OCE, Pred, NewState,
nullptr,
2167 caseStmt::CallExprClass:
2168 caseStmt::CXXMemberCallExprClass:
2169 caseStmt::UserDefinedLiteralClass:
2175 caseStmt::CXXCatchStmtClass:
2181 caseStmt::CXXTemporaryObjectExprClass:
2182 caseStmt::CXXConstructExprClass:
2188 caseStmt::CXXInheritedCtorInitExprClass:
2195 caseStmt::CXXNewExprClass: {
2202 for(
const autoi : PreVisit)
2210 caseStmt::CXXDeleteExprClass: {
2213 const auto*CDE = cast<CXXDeleteExpr>(S);
2227 caseStmt::ChooseExprClass: {
2229 const auto*
C= cast<ChooseExpr>(S);
2235 caseStmt::CompoundAssignOperatorClass:
2241 caseStmt::CompoundLiteralExprClass:
2247 caseStmt::BinaryConditionalOperatorClass:
2248 caseStmt::ConditionalOperatorClass: {
2250 const auto*
C= cast<AbstractConditionalOperator>(S);
2256 caseStmt::CXXThisExprClass:
2262 caseStmt::DeclRefExprClass: {
2264 const auto*DE = cast<DeclRefExpr>(S);
2270 caseStmt::DeclStmtClass:
2276 caseStmt::ImplicitCastExprClass:
2277 caseStmt::CStyleCastExprClass:
2278 caseStmt::CXXStaticCastExprClass:
2279 caseStmt::CXXDynamicCastExprClass:
2280 caseStmt::CXXReinterpretCastExprClass:
2281 caseStmt::CXXConstCastExprClass:
2282 caseStmt::CXXFunctionalCastExprClass:
2283 caseStmt::BuiltinBitCastExprClass:
2284 caseStmt::ObjCBridgedCastExprClass:
2285 caseStmt::CXXAddrspaceCastExprClass: {
2287 const auto*
C= cast<CastExpr>(S);
2297 caseExpr::MaterializeTemporaryExprClass: {
2299 const auto*MTE = cast<MaterializeTemporaryExpr>(S);
2303 for(
const autoi : dstPrevisit)
2310 caseStmt::InitListExprClass:
2316 caseStmt::MemberExprClass:
2322 caseStmt::AtomicExprClass:
2328 caseStmt::ObjCIvarRefExprClass:
2334 caseStmt::ObjCForCollectionStmtClass:
2340 caseStmt::ObjCMessageExprClass:
2346 caseStmt::ObjCAtThrowStmtClass:
2347 caseStmt::CXXThrowExprClass:
2353 caseStmt::ReturnStmtClass:
2359 caseStmt::OffsetOfExprClass: {
2365 for(
const auto Node: PreVisit)
2373 caseStmt::UnaryExprOrTypeTraitExprClass:
2380 caseStmt::StmtExprClass: {
2381 const auto*SE = cast<StmtExpr>(S);
2383 if(SE->getSubStmt()->body_empty()) {
2386&&
"Empty statement expression must have void type.");
2390 if(
const auto*LastExpr =
2391dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
2395state->getSVal(LastExpr,
2401 caseStmt::UnaryOperatorClass: {
2403 const auto*
U= cast<UnaryOperator>(S);
2404 if(AMgr.
options.ShouldEagerlyAssume && (
U->getOpcode() == UO_LNot)) {
2415 caseStmt::PseudoObjectExprClass: {
2418 const auto*PE = cast<PseudoObjectExpr>(S);
2419 if(
const Expr*
Result= PE->getResultExpr()) {
2433 caseExpr::ObjCIndirectCopyRestoreExprClass: {
2439 const auto*OIE = cast<ObjCIndirectCopyRestoreExpr>(S);
2440 const Expr*
E= OIE->getSubExpr();
2450boolExprEngine::replayWithoutInlining(
ExplodedNode*N,
2454assert(CalleeSF && CallerSF);
2461BeforeProcessingCall = N;
2476 if(SP->getStmt() == CE)
2481 if(!BeforeProcessingCall)
2498 boolIsNew =
false;
2510NumTimesRetriedWithoutInlining++;
2521 if(AMgr.
options.ShouldUnrollLoops) {
2526Pred, maxBlockVisitOnPath);
2527 if(NewState != Pred->
getState()) {
2543AMgr.
options.ShouldWidenLoops) {
2545 if(!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
2566(*G.
roots_begin())->getLocation().getLocationContext();
2575replayWithoutInlining(Pred, CalleeLC)))
2577NumMaxBlockCountReachedInInlined++;
2579NumMaxBlockCountReached++;
2582Engine.blocksExhausted.push_back(std::make_pair(L, Sink));
2600 const auto*Ex = dyn_cast<Expr>(
Condition);
2605 boolbitsInit =
false;
2607 while(
const auto*CE = dyn_cast<CastExpr>(Ex)) {
2614 if(!bitsInit || newBits < bits) {
2619Ex = CE->getSubExpr();
2629 returnstate->getSVal(Ex, LCtx);
2635 const auto*BO = dyn_cast<BinaryOperator>(
Condition);
2636 if(!BO || !BO->isLogicalOp()) {
2639 Condition= BO->getRHS()->IgnoreParens();
2661 if(
const auto*Ex = dyn_cast<Expr>(
Condition))
2664 const auto*BO = dyn_cast<BinaryOperator>(
Condition);
2665 if(!BO || !BO->isLogicalOp())
2669 "Other kinds of branches are handled separately!");
2680std::optional<CFGStmt> CS = Elem.getAs<
CFGStmt>();
2683 const Stmt*LastStmt = CS->getStmt();
2687llvm_unreachable(
"could not resolve condition");
2691std::pair<const ObjCForCollectionStmt *, const LocationContext *>;
2698assert(!State->contains<ObjCForHasMoreIterations>({O, LC}));
2699 returnState->set<ObjCForHasMoreIterations>({O, LC}, HasMoreIteraton);
2706assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
2707 returnState->remove<ObjCForHasMoreIterations>({O, LC});
2713assert(State->contains<ObjCForHasMoreIterations>({O, LC}));
2714 return*State->get<ObjCForHasMoreIterations>({O, LC});
2720staticstd::optional<std::pair<ProgramStateRef, ProgramStateRef>>
2723 if(
const auto*ObjCFor = dyn_cast<ObjCForCollectionStmt>(
Condition)) {
2724 boolHasMoreIteraton =
2731 if(HasMoreIteraton)
2732 returnstd::pair<ProgramStateRef, ProgramStateRef>{State,
nullptr};
2734 returnstd::pair<ProgramStateRef, ProgramStateRef>{
nullptr, State};
2738 if(
X.isUnknownOrUndef()) {
2740 if(
const auto*Ex = dyn_cast<Expr>(
Condition)) {
2741 if(Ex->getType()->isIntegralOrEnumerationType()) {
2748N->
getState()->getStateManager().getContext());
2758 if(
X.isUnknownOrUndef())
2759 returnstd::nullopt;
2764 returnState->assume(
V);
2770std::optional<unsigned> IterationsCompletedInLoop) {
2772 "CXXBindTemporaryExprs are handled by processBindTemporary.");
2775currBldrCtx = &BldCtx;
2784 if(
const auto*Ex = dyn_cast<Expr>(
Condition))
2790 "Error evaluating branch");
2796 if(CheckersOutSet.
empty())
2801 if(PredN->isSink())
2808std::tie(StTrue, StFalse) = *KnownCondValueAssumption;
2810 if(StTrue && StFalse)
2811assert(!isa<ObjCForCollectionStmt>(
Condition));
2829 boolCompletedTwoIterations = IterationsCompletedInLoop.value_or(0) >= 2;
2830 boolFalseAlsoFeasible =
2833 boolSkipTrueBranch = CompletedTwoIterations && FalseAlsoFeasible;
2839 if(!SkipTrueBranch || AMgr.
options.ShouldWidenLoops)
2840Builder.generateNode(StTrue,
true, PredN);
2844Builder.generateNode(StFalse,
false, PredN);
2846currBldrCtx =
nullptr;
2852llvm::ImmutableSet<const VarDecl *>)
2861currBldrCtx = &BuilderCtx;
2865 boolinitHasRun = state->contains<InitializedGlobalsSet>(VD);
2869state = state->add<InitializedGlobalsSet>(VD);
2872Builder.generateNode(state, initHasRun, Pred);
2874currBldrCtx =
nullptr;
2892 if(std::optional<loc::GotoLabel> LV =
V.getAs<
loc::GotoLabel>()) {
2895 for(iterator Succ : builder) {
2896 if(Succ.getLabel() == L) {
2897builder.generateNode(Succ, state);
2902llvm_unreachable(
"No block with label.");
2905 if(isa<UndefinedVal, loc::ConcreteInt>(
V)) {
2916 for(iterator Succ : builder)
2936State = finishArgumentConstruction(
2951 while(LC != ToLC) {
2952assert(LC &&
"ToLC must be a parent of FromLC!");
2953 for(
autoI : State->get<ObjectsUnderConstruction>())
2954 if(I.first.getLocationContext() == LC) {
2958assert(I.first.getItem().getKind() ==
2960I.first.getItem().getKind() ==
2962State = State->remove<ObjectsUnderConstruction>(I.first);
2980assert(areAllObjectsFullyConstructed(Pred->
getState(),
2993 for(
const autoI : AfterRemovedDead)
3011 if(CondV_untested.
isUndef()) {
3022iterator I = builder.
begin(), EI = builder.
end();
3023 booldefaultIsFeasible = I == EI;
3025 for( ; I != EI; ++I) {
3030 const CaseStmt*Case = I.getCase();
3044 if(std::optional<NonLoc> NL = CondV.
getAs<
NonLoc>())
3045std::tie(StateCase, DefaultSt) =
3046DefaultSt->assumeInclusiveRange(*NL, V1, V2);
3048StateCase = DefaultSt;
3056defaultIsFeasible =
true;
3058defaultIsFeasible =
false;
3063 if(!defaultIsFeasible)
3095 if(
const auto*VD = dyn_cast<VarDecl>(
D)) {
3098assert(Ex->
isGLValue() || VD->getType()->isVoidType());
3101 const auto*MD = dyn_cast_or_null<CXXMethodDecl>(
D);
3102 const auto*DeclRefEx = dyn_cast<DeclRefExpr>(Ex);
3103std::optional<std::pair<SVal, QualType>> VInfo;
3105 if(AMgr.
options.ShouldInlineLambdas && DeclRefEx &&
3106DeclRefEx->refersToEnclosingVariableOrCapture() && MD &&
3107MD->getParent()->isLambda()) {
3110llvm::DenseMap<const ValueDecl *, FieldDecl *> LambdaCaptureFields;
3116 if(
const FieldDecl*FD = LambdaCaptureFields[VD]) {
3120VInfo = std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
3125VInfo = std::make_pair(state->getLValue(VD, LocCtxt), VD->getType());
3127 SVal V= VInfo->first;
3128 boolIsReference = VInfo->second->isReferenceType();
3134 V= state->getSVal(R);
3139Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3143 if(
const auto*ED = dyn_cast<EnumConstantDecl>(
D)) {
3146Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V));
3149 if(
const auto*FD = dyn_cast<FunctionDecl>(
D)) {
3151Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3155 if(isa<FieldDecl, IndirectFieldDecl>(
D)) {
3160 if(
const auto*BD = dyn_cast<BindingDecl>(
D)) {
3161 const auto*DD = cast<DecompositionDecl>(BD->getDecomposedDecl());
3163 SVal Base= state->getLValue(DD, LCtx);
3164 if(DD->getType()->isReferenceType()) {
3166 Base= state->getSVal(R);
3174 if(
const auto*ME = dyn_cast<MemberExpr>(BD->getBinding())) {
3175 const auto*Field = cast<FieldDecl>(ME->getMemberDecl());
3176 V= state->getLValue(Field,
Base);
3179 else if(
const auto*ASE = dyn_cast<ArraySubscriptExpr>(BD->getBinding())) {
3180 SValIdx = state->getSVal(ASE->getIdx(), LCtx);
3185assert(Idx.
isConstant() &&
"BindingDecl array index is not a constant!");
3187 V= state->getLValue(BD->getType(), Idx,
Base);
3190 else if(
const auto*HV = BD->getHoldingVar()) {
3191 V= state->getLValue(HV, LCtx);
3193 if(HV->getType()->isReferenceType()) {
3195 V= state->getSVal(R);
3200llvm_unreachable(
"An unknown case of structured binding encountered!");
3204 if(BD->getType()->isReferenceType() && !BD->getHoldingVar()) {
3206 V= state->getSVal(R);
3211Bldr.
generateNode(Ex, Pred, state->BindExpr(Ex, LCtx,
V),
nullptr,
3217 if(
const auto*TPO = dyn_cast<TemplateParamObjectDecl>(
D)) {
3223llvm_unreachable(
"Support for this Decl not implemented.");
3238 for(
auto*
Node: CheckerPreStmt) {
3241 if(isa<CXXConstructExpr>(Ex->
getSubExpr()))
3283 if(
const auto*ME = dyn_cast<MemberExpr>(Arr)) {
3284 Expr*MEBase = ME->getBase();
3287 if(
autoCXXSCE = dyn_cast<CXXStaticCastExpr>(MEBase)) {
3288MEBase = CXXSCE->getSubExpr();
3291 autoObjDeclExpr = cast<DeclRefExpr>(MEBase);
3292 SValObj = state->getLValue(cast<VarDecl>(ObjDeclExpr->getDecl()), LCtx);
3294 Base= state->getLValue(cast<FieldDecl>(ME->getMemberDecl()), Obj);
3309 if(
const DeclRefExpr*DRE = dyn_cast<DeclRefExpr>(Arr))
3310 Base= state->getLValue(cast<VarDecl>(DRE->getDecl()), LCtx);
3314 Base= state->getSVal(R);
3342 boolIsGLValueLike = A->
isGLValue() ||
3345 for(
auto*
Node: CheckerPreStmt) {
3349 if(IsGLValueLike) {
3358 SVal V= state->getLValue(
T,
3359state->getSVal(Idx, LCtx),
3360state->getSVal(
Base, LCtx));
3363}
else if(IsVectorType) {
3367llvm_unreachable(
"Array subscript should be an lValue when not \ 3368a vector and not a forbidden lvalue type");
3387 if(isa<VarDecl, EnumConstantDecl>(
Member)) {
3388 for(
const autoI : CheckedSet)
3394 for(
const autoI : CheckedSet) {
3400 if(
const auto*MD = dyn_cast<CXXMethodDecl>(
Member)) {
3401 if(MD->isImplicitObjectMemberFunction())
3402state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
3405state = state->BindExpr(M, LCtx, MDVal);
3413state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr,
3420 if(
const auto*SR =
3421dyn_cast_or_null<SymbolicRegion>(baseExprVal.
getAsRegion())) {
3422 QualType T= SR->getPointeeStaticType();
3427 const auto*field = cast<FieldDecl>(
Member);
3428 SValL = state->getLValue(field, baseExprVal);
3438dyn_cast<ImplicitCastExpr>(I->getParentMap().getParentIgnoreParens(M));
3439 if(!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
3440llvm_unreachable(
"should always be wrapped in ArrayToPointerDecay");
3444 if(field->getType()->isReferenceType()) {
3446L = state->getSVal(R);
3451Bldr.
generateNode(M, I, state->BindExpr(M, LCtx, L),
nullptr,
3475 for(
const autoI : AfterPreSet) {
3480 for(
unsignedSI = 0, Count = AE->
getNumSubExprs(); SI != Count; SI++) {
3482 SValSubExprVal = State->getSVal(SubExpr, LCtx);
3483ValuesToInvalidate.push_back(SubExprVal);
3486State = State->invalidateRegions(ValuesToInvalidate, AE,
3493State = State->BindExpr(AE, LCtx, ResultVal);
3513 for(
conststd::pair<SVal, SVal> &LocAndVal : LocAndVals) {
3515 const MemRegion*MR = LocAndVal.first.getAsRegion();
3517!isa<StackSpaceRegion, StaticGlobalSpaceRegion>(MR->
getMemorySpace())) {
3518Escaped.push_back(LocAndVal.second);
3523 if(
const auto*VR = dyn_cast<VarRegion>(MR->
getBaseRegion()))
3524 if(VR->hasStackParametersStorage() && VR->getStackFrame()->inTopFrame())
3525 if(
const auto*RD = VR->getValueType()->getAsCXXRecordDecl())
3526 if(!RD->hasTrivialDestructor()) {
3527Escaped.push_back(LocAndVal.second);
3536 SValStoredVal = State->getSVal(MR);
3537 if(StoredVal != LocAndVal.second)
3540Escaped.push_back(LocAndVal.second);
3543 if(Escaped.empty())
3546 returnescapeValues(State, Escaped, Kind,
Call);
3552std::pair<SVal, SVal> LocAndVal(
Loc, Val);
3563 if(!Invalidated || Invalidated->empty())
3576 for(
const autoI : ExplicitRegions) {
3578SymbolsDirectlyInvalidated.insert(R->getSymbol());
3582 for(
const auto&sym : *Invalidated) {
3583 if(SymbolsDirectlyInvalidated.count(sym))
3585SymbolsIndirectlyInvalidated.insert(sym);
3588 if(!SymbolsDirectlyInvalidated.empty())
3593 if(!SymbolsIndirectlyInvalidated.empty())
3614StoreE, *
this, *PP);
3620 if(!isa<Loc>(location)) {
3625Bldr.generateNode(L, state, Pred);
3629 for(
const autoPredI : CheckedSet) {
3637state = state->bindLoc(location.
castAs<
Loc>(),
3638Val, LC,
!atDeclInit);
3641 if(std::optional<loc::MemRegionVal> LocRegVal =
3643LocReg = LocRegVal->getRegion();
3647Bldr.generateNode(L, state, PredI);
3660 const Expr*LocationE,
3666 const Expr*StoreE = AssignE ? AssignE : LocationE;
3670evalLocation(Tmp, AssignE, LocationE, Pred, state, location,
false);
3678 for(
const autoI : Tmp)
3679evalBind(Dst, StoreE, I, location, Val,
false);
3684 const Expr*BoundEx,
3690assert(!isa<NonLoc>(location) &&
"location cannot be a NonLoc.");
3695evalLocation(Tmp, NodeEx, BoundEx, Pred, state, location,
true);
3704 for(
const autoI : Tmp) {
3705state = I->getState();
3711LoadTy = BoundEx->
getType();
3712 V= state->getSVal(location.
castAs<
Loc>(), LoadTy);
3715Bldr.
generateNode(NodeEx, I, state->BindExpr(BoundEx, LCtx,
V), tag,
3722 const Stmt*BoundEx,
3734BldrTop.takeNodes(Pred);
3747Bldr.generateNode(NodeEx, Pred, state, &tag);
3751NodeEx, BoundEx, *
this);
3752BldrTop.addNodes(Tmp);
3755std::pair<const ProgramPointTag *, const ProgramPointTag *>
3758FalseTag(TagProviderName,
"Eagerly Assume False");
3760 returnstd::make_pair(&TrueTag, &FalseTag);
3784State = State->set<LastEagerlyAssumeExprIfSuccessful>(
nullptr);
3787 if(SEV && SEV->isExpression()) {
3790 auto[StateTrue, StateFalse] = State->assume(*SEV);
3792 if(StateTrue && StateFalse) {
3793StateTrue = StateTrue->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3794StateFalse = StateFalse->set<LastEagerlyAssumeExprIfSuccessful>(Ex);
3815 const Expr*Ex)
const{
3816 returnEx && State->get<LastEagerlyAssumeExprIfSuccessful>() == Ex;
3833assert(!isa<NonLoc>(
X));
3835 if(std::optional<Loc> LV =
X.getAs<
Loc>())
3836state = state->invalidateRegions(*LV, A, currBldrCtx->
blockCount(),
3845 if(std::optional<Loc> LV =
X.getAs<
Loc>())
3846state = state->invalidateRegions(*LV, A, currBldrCtx->
blockCount(),
3872N->
getState()->getStateManager().getOwningEngine()).getBugReporter();
3875 for(
const auto&
Report:
Class.getReports()) {
3876 const auto*PR = dyn_cast<PathSensitiveBugReport>(
Report.get());
3894llvm::function_ref<
void(
const ExplodedNode*)> PreCallback,
3895llvm::function_ref<
void(
const ExplodedNode*)> PostCallback,
3896llvm::function_ref<
bool(
const ExplodedNode*)> Stop) {
3917llvm::raw_string_ostream Out(Buf);
3919 const boolIsDot =
true;
3920 const unsigned intSpace = 1;
3923Out <<
"{ \"state_id\": "<< State->getID()
3926Indent(Out, Space, IsDot) <<
"\"program_points\": [\\l";
3929traverseHiddenNodes(
3932Indent(Out, Space + 1, IsDot) <<
"{ ";
3934Out <<
", \"tag\": ";
3936Out <<
'\"'<< Tag->getTagDescription() <<
'\"';
3939Out <<
", \"node_id\": "<< OtherNode->
getID() <<
3940 ", \"is_sink\": "<< OtherNode->
isSink() <<
3941 ", \"has_report\": "<< nodeHasBugReport(OtherNode) <<
" }";
3948Indent(Out, Space, IsDot) <<
"],\\l";
3961llvm::DisplayGraph(
Filename,
false, llvm::GraphProgram::DOT);
3966llvm::DisplayGraph(
Filename,
false, llvm::GraphProgram::DOT);
3971std::vector<const ExplodedNode *> Src;
3976dyn_cast<PathSensitiveBugReport>(
Class.getReports()[0].get());
3979 const auto*N =
const_cast<ExplodedNode*
>(R->getErrorNode());
3985 returnllvm::WriteGraph(&G,
"ExprEngine",
false,
3992std::unique_ptr<ExplodedGraph> TrimmedG(G.
trim(
Nodes));
3994 if(!TrimmedG.get()) {
3995llvm::errs() <<
"warning: Trimmed ExplodedGraph is empty.\n";
3999 returnllvm::WriteGraph(TrimmedG.get(),
"TrimmedExprEngine",
4001 "Trimmed Exploded Graph",
4006 static intindex = 0;
4010voidExprEngine::anchor() { }
Defines the clang::ASTContext interface.
BoundNodesTreeBuilder Nodes
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
static const MemRegion * getRegion(const CallEvent &Call, const MutexDescriptor &Descriptor, bool IsLock)
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
static const Stmt * getRightmostLeaf(const Stmt *Condition)
std::pair< const ObjCForCollectionStmt *, const LocationContext * > ObjCForLctxPair
static SVal RecoverCastedSymbol(ProgramStateRef state, const Stmt *Condition, const LocationContext *LCtx, ASTContext &Ctx)
RecoverCastedSymbol - A helper function for ProcessBranch that is used to try to recover some path-se...
static void printObjectsUnderConstructionJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const LocationContext *LCtx, unsigned int Space=0, bool IsDot=false)
static void printIndicesOfElementsToConstructJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const LocationContext *LCtx, unsigned int Space=0, bool IsDot=false)
static void printStateTraitWithLocationContextJson(raw_ostream &Out, ProgramStateRef State, const LocationContext *LCtx, const char *NL, unsigned int Space, bool IsDot, const char *jsonPropertyName, Printer printer, Args &&...args)
A helper function to generalize program state trait printing.
static void printPendingArrayDestructionsJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const LocationContext *LCtx, unsigned int Space=0, bool IsDot=false)
static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S, const ExplodedNode *Pred, const LocationContext *LC)
static const Stmt * ResolveCondition(const Stmt *Condition, const CFGBlock *B)
REGISTER_TRAIT_WITH_PROGRAMSTATE(ObjectsUnderConstruction, ObjectsUnderConstructionMap) typedef llvm REGISTER_TRAIT_WITH_PROGRAMSTATE(IndexOfElementToConstruct, IndexOfElementToConstructMap) typedef llvm typedef llvm::ImmutableMap< const LocationContext *, unsigned > PendingArrayDestructionMap
static void printPendingInitLoopJson(raw_ostream &Out, ProgramStateRef State, const char *NL, const LocationContext *LCtx, unsigned int Space=0, bool IsDot=false)
llvm::ImmutableMap< ConstructedObjectKey, SVal > ObjectsUnderConstructionMap
static std::optional< std::pair< ProgramStateRef, ProgramStateRef > > assumeCondition(const Stmt *Condition, ExplodedNode *N)
Split the state on whether there are any more iterations left for this loop.
STATISTIC(NumRemoveDeadBindings, "The # of times RemoveDeadBindings is called")
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
This header contains the declarations of functions which are used to decide which loops should be com...
This header contains the declarations of functions which are used to widen loops which do not otherwi...
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
#define REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, Type)
Declares a program state trait for type Type called Name, and introduce a type named NameTy.
static bool isRecordType(QualType T)
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Defines the Objective-C statement AST node classes.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
ParentMap & getParentMap()
ASTContext & getASTContext() const
Stores options for the analyzer from the command line.
unsigned NoRetryExhausted
Do not re-analyze paths leading to exhausted nodes with a different strategy.
unsigned maxBlockVisitOnPath
The maximum number of times the analyzer visits a block.
AnalysisPurgeMode AnalysisPurgeOpt
Represents a loop initializing the elements of an array.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Expr * getSubExpr() const
Get the initializer to use for each array element.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
static unsigned getNumSubExprs(AtomicOp Op)
Determine the number of arguments the specified atomic builtin should have.
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
const VarDecl * getVarDecl() const
const Stmt * getTriggerStmt() const
Represents C++ object destructor implicitly generated for base object in destructor.
Represents a single basic block in a source-level CFG.
CFGTerminator getTerminator() const
Stmt * getTerminatorStmt()
Represents C++ object destructor generated from a call to delete.
const CXXDeleteExpr * getDeleteExpr() const
Represents a top-level expression in a basic block.
Represents C++ object destructor implicitly generated by compiler on various occasions.
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
Represents C++ base or member initializer from constructor's initialization list.
CXXCtorInitializer * getInitializer() const
Represents the point where a loop ends.
const Stmt * getLoopStmt() const
Represents C++ object destructor implicitly generated for member object in destructor.
Represents C++ allocator call.
const CXXNewExpr * getAllocatorExpr() const
const Stmt * getStmt() const
Represents C++ object destructor implicitly generated at the end of full expression for temporary obj...
bool isStmtBranch() const
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
Represents a call to a C++ constructor.
Represents a C++ base or member initializer.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
bool isDelegatingInitializer() const
Determine whether this initializer is creating a delegating constructor.
Expr * getInit() const
Get the initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
int64_t getID(const ASTContext &Context) const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a delete expression for memory deallocation and destructor calls, e.g.
SourceLocation getBeginLoc() const
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ destructor within a class.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++ struct/union/class.
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Represents a point when we begin processing an inlined call.
CaseStmt - Represent a case statement.
Represents a single point (AST node) in the program that requires attention during construction of an...
unsigned getIndex() const
If a single trigger statement triggers multiple constructors, they are usually being enumerated.
const CXXCtorInitializer * getCXXCtorInitializer() const
The construction site is not necessarily a statement.
@ TemporaryDestructorKind
const Stmt * getStmtOrNull() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
const Decl * getSingleDecl() const
Decl - This represents one declaration (or definition), e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This is a meta program point, which should be skipped by all the diagnostic reasoning etc.
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Represents a member of a struct/union/class.
This represents a GCC inline-assembly statement extension.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Represents the declaration of a label.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
const Decl * getDecl() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const LocationContext * getParent() const
It might return null.
const StackFrameContext * getStackFrame() const
virtual bool inTopFrame() const
void printJson(raw_ostream &Out, const char *NL="\n", unsigned int Space=0, bool IsDot=false, std::function< void(const LocationContext *)> printMoreInfoPerContext=[](const LocationContext *) {}) const
Prints out the call stack in json format.
Represents a point when we exit a loop.
This represents a Microsoft inline-assembly statement extension.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents Objective-C's collection statement.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
bool isConsumedExpr(Expr *E) const
Represents a parameter to a function.
Represents a program point just after an implicit call event.
Represents a program point after a store evaluation.
Represents a program point just before an implicit call event.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
const ProgramPointTag * getTag() const
bool isPurgeKind()
Is this a program point corresponding to purge/removal of dead symbols and bindings.
void printJson(llvm::raw_ostream &Out, const char *NL="\n") const
@ PreStmtPurgeDeadSymbolsKind
@ PostStmtPurgeDeadSymbolsKind
const StackFrameContext * getStackFrame() const
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
const LocationContext * getLocationContext() const
A (possibly-)qualified type.
QualType getDesugaredType(const ASTContext &Context) const
Return the specified type with any "sugar" removed from the type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
SplitQualType split() const
Divides a QualType into its unqualified type and a set of local qualifiers.
bool isCForbiddenLValueType() const
Determine whether expressions of the given type are forbidden from being lvalues in C.
std::string getAsString() const
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
std::string printToString(const SourceManager &SM) const
It represents a stack frame of the call stack (based on CallEvent).
unsigned getIndex() const
const Stmt * getCallSite() const
const CFGBlock * getCallSiteBlock() const
bool inTopFrame() const override
const Stmt * getStmt() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const char * getStmtClassName() const
int64_t getID(const ASTContext &Context) const
SourceLocation getBeginLoc() const LLVM_READONLY
SwitchStmt - This represents a 'switch' stmt.
bool isAllEnumCasesCovered() const
Returns true if the SwitchStmt is a switch of an enum value and all cases have been explicitly covere...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isReferenceType() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isVectorType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
This class is used for tools that requires cross translation unit capability.
const LangOptions & getLangOpts() const
ASTContext & getASTContext() override
AnalyzerOptions & options
BranchNodeBuilder is responsible for constructing the nodes corresponding to the two branches of the ...
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 runCheckersForBind(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, SVal val, const Stmt *S, ExprEngine &Eng, const ProgramPoint &PP)
Run checkers for binding of a value to a location.
void runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS)
Run checkers on end of function.
void runCheckersForLocation(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SVal location, bool isLoad, const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &Eng)
Run checkers for load/store of a location.
void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng)
Run checkers for end of analysis.
void runCheckersForPrintStateJson(raw_ostream &Out, ProgramStateRef State, const char *NL="\n", unsigned int Space=0, bool IsDot=false) const
Run checkers for debug-printing a ProgramState.
void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, SymbolReaper &SymReaper, const Stmt *S, ExprEngine &Eng, ProgramPoint::Kind K)
Run checkers for dead symbols.
ProgramStateRef runCheckersForRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call)
Run checkers for region changes.
void runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper)
Run checkers for live symbols.
void runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers on beginning of function.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
void runCheckersForBranchCondition(const Stmt *condition, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng)
Run checkers for branch condition.
ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)
Run checkers when pointers escape.
ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption)
Run checkers for handling assumptions on symbolic values.
virtual ProgramStateRef removeDeadBindings(ProgramStateRef state, SymbolReaper &SymReaper)=0
Scan all symbols referenced by the constraints.
void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block)
Inform the CoreEngine that a basic block was aborted because it could not be completely analyzed.
void enqueueStmtNode(ExplodedNode *N, const CFGBlock *Block, unsigned Idx)
Enqueue a single node created as a result of statement processing.
void enqueueEndOfFunction(ExplodedNodeSet &Set, const ReturnStmt *RS)
enqueue the nodes corresponding to the end of function onto the end of path / work list.
void enqueue(ExplodedNodeSet &Set)
Enqueue the given set of nodes onto the work list.
std::unique_ptr< ExplodedGraph > trim(ArrayRef< const NodeTy * > Nodes, InterExplodedGraphMap *ForwardMap=nullptr, InterExplodedGraphMap *InverseMap=nullptr) const
Creates a trimmed version of the graph that only contains paths leading to the given nodes.
void enableNodeReclamation(unsigned Interval)
Enable tracking of recently allocated nodes for potential reclamation when calling reclaimRecentlyAll...
void reclaimRecentlyAllocatedNodes()
Reclaim "uninteresting" nodes created since the last time this method was called.
ExplodedNode * getNode(const ProgramPoint &L, ProgramStateRef State, bool IsSink=false, bool *IsNew=nullptr)
Retrieve the node associated with a (Location,State) pair, where the 'Location' is a ProgramPoint in ...
roots_iterator roots_begin()
void insert(const ExplodedNodeSet &S)
void Add(ExplodedNode *N)
const ProgramStateRef & getState() const
pred_iterator pred_begin()
bool isTrivial() const
The node is trivial if it has only one successor, only one predecessor, it's predecessor has only one...
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
ExplodedNode * getFirstSucc()
const StackFrameContext * getStackFrame() const
const LocationContext * getLocationContext() const
unsigned succ_size() const
void processEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, const ReturnStmt *RS=nullptr)
Called by CoreEngine.
void VisitBinaryOperator(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitBinaryOperator - Transfer function logic for binary operators.
ProgramStateManager & getStateManager()
void VisitArraySubscriptExpr(const ArraySubscriptExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArraySubscriptExpr - Transfer function for array accesses.
void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred)
void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGuardedExpr - Transfer function logic for ?, __builtin_choose.
void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L)
Called by CoreEngine.
void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCast - Transfer function logic for all casts (implicit and explicit).
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const LocationContext *LC, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer's garbage collection - remove dead symbols and bindings from the state.
void VisitLogicalExpr(const BinaryOperator *B, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLogicalExpr - Transfer function logic for '&&', '||'.
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)
void 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...
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.
CFGBlock::ConstCFGElementRef getCFGElementRef() const
void VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitGCCAsmStmt - Transfer function logic for inline asm.
void processCFGBlockEntrance(const BlockEdge &L, NodeBuilderWithSinks &nodeBuilder, ExplodedNode *Pred)
Called by CoreEngine when processing the entrance of a CFGBlock.
void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef< const MemRegion * > ExplicitRegions, ArrayRef< const MemRegion * > Regions, const LocationContext *LCtx, const CallEvent *Call)
processRegionChanges - Called by ProgramStateManager whenever a change is made to the store.
void ProcessStmt(const Stmt *S, ExplodedNode *Pred)
ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr, SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn)
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
static std::optional< unsigned > getPendingArrayDestruction(ProgramStateRef State, const LocationContext *LCtx)
Retreives which element is being destructed in a non-POD type array.
ProgramStateRef notifyCheckersOfPointerEscape(ProgramStateRef State, const InvalidatedSymbols *Invalidated, ArrayRef< const MemRegion * > ExplicitRegions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits)
Call PointerEscape callback when a value escapes as a result of region invalidation.
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 VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof.
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
void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAtomicExpr - Transfer function for builtin atomic expressions.
void ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitMemberExpr - Transfer function for member expressions.
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
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()
void ProcessDeleteDtor(const CFGDeleteDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCompoundLiteralExpr - Transfer function logic for compound literals.
SValBuilder & getSValBuilder()
void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitArrayInitLoopExpr - Transfer function for array init loop.
void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE, ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val, const ProgramPointTag *tag=nullptr)
evalStore - Handle the semantics of a store via an assignment.
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, ExplodedNodeSet &PreVisit, ExplodedNodeSet &Dst)
void processIndirectGoto(IndirectGotoNodeBuilder &builder)
processIndirectGoto - Called by CoreEngine.
const NodeBuilderContext & getBuilderContext()
static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retreives the size of the array in the pending ArrayInitLoopExpr.
void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred)
void markReachedMaxBlockCount(const Decl *D)
const Expr * getTarget() const
const LocationContext * getLocationContext() const
ProgramStateRef getState() const
ExplodedNode * generateNode(const iterator &I, ProgramStateRef State, bool isSink=false)
static bool isLocType(QualType T)
const CXXLifetimeExtendedObjectRegion * getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD, LocationContext const *LC)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by local referen...
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
const CXXLifetimeExtendedObjectRegion * getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by static refere...
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
const CFGBlock * getBlock() const
Return the CFGBlock associated with this builder.
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
This node builder keeps track of the generated sink nodes.
ExplodedNode * generateNode(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
ExplodedNode * generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag=nullptr)
This is the simplest builder which generates nodes in the ExplodedGraph.
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
void takeNodes(const ExplodedNodeSet &S)
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
void addNodes(const ExplodedNodeSet &S)
const NodeBuilderContext & getContext()
While alive, includes the current analysis stack in a crash trace.
ProgramStateRef removeDeadBindingsFromEnvironmentAndStore(ProgramStateRef St, const StackFrameContext *LCtx, SymbolReaper &SymReaper)
bool haveEqualStores(ProgramStateRef S1, ProgramStateRef S2) const
bool haveEqualEnvironments(ProgramStateRef S1, ProgramStateRef S2) const
ProgramStateRef getPersistentStateWithGDM(ProgramStateRef FromState, ProgramStateRef GDMState)
MemRegionManager & getRegionManager()
ProgramStateRef getInitialState(const LocationContext *InitLoc)
StoreManager & getStoreManager()
Information about invalidation for a particular region/symbol.
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
DefinedSVal getFunctionPointer(const FunctionDecl *func)
NonLoc makeIntValWithWidth(QualType ptrType, uint64_t integer)
NonLoc makeArrayIndex(uint64_t idx)
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
QualType getConditionType() const
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
std::optional< SVal > getConstantVal(const Expr *E)
Returns the value of E, if it can be determined in a non-path-sensitive manner.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
bool isUnknownOrUndef() const
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
const llvm::APSInt * getAsInteger() const
If this SVal is loc::ConcreteInt or nonloc::ConcreteInt, return a pointer to APSInt which is held in ...
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
This builder class is useful for generating nodes that resulted from visiting a statement.
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
virtual SVal getLValueField(const FieldDecl *D, SVal Base)
SubRegion - A region that subsets another larger region.
ProgramStateRef getState() const
const Expr * getCondition() const
ExplodedNode * generateDefaultCaseNode(ProgramStateRef State, bool isSink=false)
ExplodedNode * generateCaseStmtNode(const iterator &I, ProgramStateRef State)
const LocationContext * getLocationContext() const
const SwitchStmt * getSwitch() const
A class responsible for cleaning up unused symbols.
void markLive(SymbolRef sym)
Unconditionally marks a symbol as live.
SymbolicRegion - A special, "non-concrete" region.
TypedValueRegion - An abstract class representing regions having a typed value.
Represents symbolic expression that isn't a location.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
llvm::DenseSet< const Decl * > SetOfConstDecls
PointerEscapeKind
Describes the different reasons a pointer escapes during analysis.
@ PSK_DirectEscapeOnCall
The pointer has been passed to a function call directly.
@ PSK_EscapeOnBind
A pointer escapes due to binding its value to a location that the analyzer cannot track.
@ PSK_IndirectEscapeOnCall
The pointer has been passed to a function indirectly.
@ PSK_EscapeOther
The reason for pointer escape is unknown.
DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB, QualType Ty)
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State)
Updates the given ProgramState.
ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState, const LocationContext *LCtx, unsigned BlockCount, const Stmt *LoopStmt)
Get the states that result from widening the loop.
llvm::DenseSet< SymbolRef > InvalidatedSymbols
bool isUnrolledState(ProgramStateRef State)
Returns if the given State indicates that is inside a completely unrolled loop.
ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx, ExplodedNode *Pred, unsigned maxVisitOnPath)
Updates the stack of loops contained by the ProgramState.
bool LE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
@ CXXThis
Parameter for C++ 'this' argument.
Diagnostic wrappers for TextAPI types for error reporting.
Describes how types, statements, expressions, and declarations should be printed.
An adjustment to be made to the temporary created when emitting a reference binding,...
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment
Hints for figuring out of a call should be inlined during evalCall().
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
bool IsArrayCtorOrDtor
This call is a constructor or a destructor for a single element within an array, a part of array cons...
Traits for storing the call processing policy inside GDM.
DOTGraphTraits(bool isSimple=false)
static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G)
static bool nodeHasBugReport(const ExplodedNode *N)
static bool traverseHiddenNodes(const ExplodedNode *N, llvm::function_ref< void(const ExplodedNode *)> PreCallback, llvm::function_ref< void(const ExplodedNode *)> PostCallback, llvm::function_ref< bool(const ExplodedNode *)> Stop)
PreCallback: callback before break.
static bool isNodeHidden(const ExplodedNode *N, const ExplodedGraph *G)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4