23#include "llvm/Support/Casting.h"
24#include "llvm/Support/Compiler.h"
25#include "llvm/Support/SaveAndRestore.h"
31#define DEBUG_TYPE "ExprEngine"
34 NumOfDynamicDispatchPathSplits,
35 "The # of times we split the path due to imprecise dynamic dispatch info");
40 "The # of times we reached inline count maximum");
47 assert(Entry->
empty());
71 Engine.enqueue(DstBegin);
77static std::pair<
const Stmt*,
79 const Stmt *S =
nullptr;
93 S = CEE->getCalleeContext()->getCallSite();
100 std::optional<CallEnter> CE;
104 }
while (!CE || CE->getCalleeContext() != CEE->getCalleeContext());
112 if (CE->getCalleeContext() == SF)
117 return std::make_pair(
nullptr,
nullptr);
122 return std::make_pair(S, Blk);
139 if (ExpectedTy == ActualTy)
168 const Stmt *LastSt =
nullptr;
171 if (!Blk || !LastSt) {
182 removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt), LCtx,
190 const Decl *StaticDecl =
Call->getDecl();
191 assert(RuntimeCallee);
202 "The call event is not a destructor call!");
206 auto ThisVal = DtorCall.getCXXThisVal();
208 if (
auto ThisElementRegion = dyn_cast<ElementRegion>(ThisVal.getAsRegion())) {
209 auto ArrayRegion = ThisElementRegion->getAsArrayOffset().getRegion();
210 auto ElementType = ThisElementRegion->getElementType();
215 if (!ElementCount.isConstant())
218 return ElementCount.getAsInteger()->getLimitedValue();
226 const LocationContext *LCtx) {
228 assert(LCtx &&
"Location context must be provided!");
232 State = removePendingInitLoop(State, E, LCtx);
235 State = removeIndexOfElementToConstruct(State, E, LCtx);
239 State = removePendingArrayDestruction(State, LCtx);
268 isa_and_nonnull<ReturnStmt>(LastSt) ? Blk : &CEBNode->
getCFG().
getExit();
284 bool ShouldRepeatCall =
false;
286 if (
const auto *DtorDecl =
287 dyn_cast_or_null<CXXDestructorDecl>(
Call->getDecl())) {
289 ShouldRepeatCall = *Idx > 0;
291 auto ThisVal = svalBuilder.getCXXThis(DtorDecl->getParent(), CalleeSF);
292 State = State->killBinding(ThisVal);
298 if (
const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
302 if (RS->getRetValue())
303 V = State->getSVal(RS->getRetValue(), LCtx);
309 if (!ReturnedTy.
isNull()) {
315 State = State->BindExpr(CE, CallerSF,
V);
321 svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), CalleeSF);
323 ThisV = State->getSVal(ThisV.
castAs<
Loc>());
324 State = State->BindExpr(CCE, CallerSF, ThisV);
326 ShouldRepeatCall = shouldRepeatCtorCall(State, CCE, CallerSF);
329 if (
const auto *CNE = dyn_cast<CXXNewExpr>(CE)) {
335 SVal AllocV = State->getSVal(CNE, CallerSF);
336 AllocV = svalBuilder.evalCast(
341 addObjectUnderConstruction(State, CNE, CalleeSF->
getParent(), AllocV);
345 if (!ShouldRepeatCall) {
346 State = removeStateTraitsUsedForArrayEvaluation(
347 State, dyn_cast_or_null<CXXConstructExpr>(CE), CallerSF);
356 if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
361 nullptr, &RetValBind)};
368 removeDead(BoundRetNode, CleanedNodes,
nullptr, CalleeSF,
372 CleanedNodes.
insert(CEBNode);
403 if (llvm::isa_and_nonnull<CXXNewExpr>(CE)) {
410 DstPostCall.
insert(DstPostPostCallCallback);
420 AMgr.getAnalyzerOptions().MayInlineCXXAllocator)) {
429 unsigned Idx = CalleeSF->
getIndex() + (ShouldRepeatCall ? 0 : 1);
448 return Cfg->
size() >= AMgr.
options.MinCFGSizeTreatFunctionsAsLarge;
456void ExprEngine::examineStackFrames(
const Decl *D,
const LocationContext *LCtx,
457 bool &IsRecursive,
unsigned &StackDepth) {
462 if (
const StackFrame *SF = dyn_cast<StackFrame>(LCtx)) {
463 const Decl *DI = SF->getDecl();
475 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI);
476 if (!isSmall(CalleeADC))
490 enum DynamicDispatchMode {
491 DynamicDispatchModeInlined = 1,
492 DynamicDispatchModeConservative
504 if (
Call.isForeign() && !isSecondPhaseCTU()) {
513 const bool BState = State->get<CTUDispatchBifurcation>();
518 ConservativeEvalState = State->set<CTUDispatchBifurcation>(
true);
519 conservativeEvalCall(
Call, Bldr, Pred, ConservativeEvalState);
521 conservativeEvalCall(
Call, Bldr, Pred, State);
535 const BlockDataRegion *BlockInvocationData =
nullptr;
539 assert(BlockInvocationData &&
540 "If we have the block definition we should have its region");
544 const Expr *CallE =
Call.getOriginExpr();
547 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
552 CallEnter Loc(CallE, CalleeSF, CurLC);
556 State = State->enterStackFrame(
Call, CalleeSF);
559 if (ExplodedNode *N = G.getNode(Loc, State,
false, &isNew)) {
560 N->addPredecessor(Pred, G);
570 Engine.FunctionSummaries->bumpNumTimesInlined(D);
579 if (!isSecondPhaseCTU())
582 VisitedCallees->insert(D);
591 assert(ReplayState == CallE &&
"Backtracked to the wrong call.");
613 evalCall(dstCallEvaluated, N, *CallTemplate);
628 const Expr *E =
Call.getOriginExpr();
635 for (
unsigned CallI = 0, CallN =
Call.getNumArgs(); CallI != CallN; ++CallI) {
636 unsigned I =
Call.getASTArgumentIndex(CallI);
641 ->getStackFrame()->getParent()
643 State = finishObjectConstruction(State, {E, I}, LC);
657 if (CleanedState == State) {
662 const Expr *E =
Call.getOriginExpr();
663 const LocationContext *LC =
Call.getLocationContext();
664 static SimpleProgramPointTag
Tag(
"ExprEngine",
665 "Finish argument construction");
666 Dst.
insert(Engine.makeNode(PreStmt(E, LC, &Tag), CleanedState, Pred));
686 dstCallEvaluated, dstPreVisit, CallTemplate, *
this,
EvalCallOptions());
692 finishArgumentConstruction(dstArgumentCleanup, I, CallTemplate);
696 CallTemplate, *
this);
720 if (
const MemRegion *MR =
Call->getArgSVal(Arg).getAsRegion())
728 if (State != I->getState())
729 I = Engine.makeNode(I->getLocation(), State, I);
738 const Expr *E =
Call.getOriginExpr();
745 switch (Msg->getMethodFamily()) {
752 return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
756 SVal ThisV =
C->getCXXThisVal();
757 ThisV = State->getSVal(ThisV.
castAs<
Loc>());
758 return State->BindExpr(E, LCtx, ThisV);
767 assert(RTC->getStmt() ==
Call.getOriginExpr());
770 Call.getOriginExpr(), State, currBldrCtx, LCtx,
771 RTC->getConstructionContext(), CallOpts);
782 State = State->invalidateRegions(TargetR, Elem, Count, LCtx,
792 const auto *CNE = dyn_cast<CXXNewExpr>(E);
793 if (CNE && CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
794 R = svalBuilder.getConjuredHeapSymbolVal(Elem, LCtx, E->
getType(), Count);
795 const MemRegion *MR = R.getAsRegion()->StripCasts();
799 if (
const Expr *SizeExpr = CNE->getArraySize().value_or(
nullptr)) {
800 ElementCount = State->getSVal(SizeExpr, LCtx);
802 ElementCount = svalBuilder.makeIntVal(1,
true);
808 svalBuilder.evalBinOp(State, BO_Mul, ElementCount, ElementSize,
809 svalBuilder.getArrayIndexType());
818 R = svalBuilder.conjureSymbolVal(Elem, LCtx, ResultTy, Count);
821 return State->BindExpr(E, LCtx, R);
836ExprEngine::CallInlinePolicy
842 switch (
Call.getKind()) {
850 return CIP_DisallowedAlways;
854 return CIP_DisallowedAlways;
864 if (llvm::isa_and_nonnull<NewAllocatedObjectConstructionContext>(CC) &&
865 !Opts.MayInlineCXXAllocator)
866 return CIP_DisallowedOnce;
869 if (!shouldInlineArrayConstruction(Pred->
getState(), CtorExpr, CurLC))
870 return CIP_DisallowedOnce;
885 return CIP_DisallowedAlways;
891 !Opts.ShouldIncludeTemporaryDtorsInCFG)
892 return CIP_DisallowedOnce;
898 return CIP_DisallowedOnce;
903 return CIP_DisallowedOnce;
915 return CIP_DisallowedAlways;
925 return CIP_DisallowedOnce;
931 !Opts.MayInlineCXXTemporaryDtors)
932 return CIP_DisallowedOnce;
938 return CIP_DisallowedOnce;
944 if (Opts.MayInlineCXXAllocator)
948 return CIP_DisallowedAlways;
950 if (!Opts.MayInlineObjCMethod)
951 return CIP_DisallowedAlways;
954 return CIP_DisallowedAlways;
999 if (II->isStr(
"shared_ptr"))
1010bool ExprEngine::mayInlineDecl(AnalysisDeclContext *CalleeADC)
const {
1011 AnalyzerOptions &Opts = AMgr.getAnalyzerOptions();
1019 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeADC->
getDecl())) {
1021 if (!Opts.MayInlineTemplateFunctions)
1026 if (!Opts.MayInlineCXXStandardLibrary)
1033 if (!Opts.MayInlineCXXContainerMethods)
1034 if (!AMgr.isInCodeFile(FD->getLocation()))
1042 if (!Opts.MayInlineCXXSharedPtrDtor)
1050 const CFG *CalleeCFG = CalleeADC->
getCFG();
1055 if (isHuge(CalleeADC))
1060 if (!CalleeADC->
getAnalysis<RelaxedLiveVariables>())
1066bool ExprEngine::shouldInlineCall(
const CallEvent &
Call,
const Decl *D,
1073 AnalyzerOptions &Opts = AMgr.options;
1074 AnalysisDeclContextManager &ADCMgr = AMgr.getAnalysisDeclContextManager();
1075 AnalysisDeclContext *CalleeADC = ADCMgr.
getContext(D);
1083 if (!AMgr.shouldInlineCall())
1087 std::optional<bool> MayInline = Engine.FunctionSummaries->mayInline(D);
1095 if (mayInlineDecl(CalleeADC)) {
1096 Engine.FunctionSummaries->markMayInline(D);
1098 Engine.FunctionSummaries->markShouldNotInline(D);
1107 CallInlinePolicy CIP = mayInlineCallKind(
Call, Pred, Opts, CallOpts);
1108 if (CIP != CIP_Allowed) {
1109 if (CIP == CIP_DisallowedAlways) {
1110 assert(!MayInline || *MayInline);
1111 Engine.FunctionSummaries->markShouldNotInline(D);
1117 bool IsRecursive =
false;
1118 unsigned StackDepth = 0;
1121 (!isSmall(CalleeADC) || IsRecursive))
1125 if ((Engine.FunctionSummaries->getNumTimesInlined(D) >
1126 Opts.MaxTimesInlineLarge) &&
1127 isLarge(CalleeADC)) {
1128 NumReachedInlineCountMax++;
1132 if (HowToInline ==
Inline_Minimal && (!isSmall(CalleeADC) || IsRecursive))
1138bool ExprEngine::shouldInlineArrayConstruction(
const ProgramStateRef State,
1139 const CXXConstructExpr *CE,
1140 const LocationContext *LCtx) {
1145 if (
const auto *CAT = dyn_cast<ConstantArrayType>(CE->
getType())) {
1156 return shouldInlineArrayDestruction(ArrSize);
1161 return shouldInlineArrayDestruction(*Size);
1166bool ExprEngine::shouldInlineArrayDestruction(uint64_t Size) {
1168 uint64_t maxAllowedSize = AMgr.options.maxBlockVisitOnPath;
1171 return Size <= maxAllowedSize && Size > 0;
1175 const CXXConstructExpr *E,
1176 const LocationContext *LCtx) {
1184 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty)) {
1217 performTrivialCopy(Bldr, Pred,
Call);
1221 const Expr *E =
Call.getOriginExpr();
1224 if (InlinedFailedState) {
1226 State = InlinedFailedState;
1231 if (shouldInlineCall(
Call, D, Pred, CallOpts)) {
1243 conservativeEvalCall(
Call, Bldr, Pred, State);
1247 ctuBifurcate(
Call, D, Bldr, Pred, State);
1254 State = removeStateTraitsUsedForArrayEvaluation(
1255 State, dyn_cast_or_null<CXXConstructExpr>(E),
Call.getLocationContext());
1258 conservativeEvalCall(
Call, Bldr, Pred, State);
1261void ExprEngine::BifurcateCall(
const MemRegion *BifurReg,
1270 const unsigned *BState =
1271 State->get<DynamicDispatchBifurcationMap>(BifurReg);
1274 if (*BState == DynamicDispatchModeInlined)
1275 ctuBifurcate(
Call, D, Bldr, Pred, State);
1279 conservativeEvalCall(
Call, Bldr, Pred, State);
1286 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1287 DynamicDispatchModeInlined);
1288 ctuBifurcate(
Call, D, Bldr, Pred, IState);
1291 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1292 DynamicDispatchModeConservative);
1293 conservativeEvalCall(
Call, Bldr, Pred, NoIState);
1295 NumOfDynamicDispatchPathSplits++;
1307 ei = dstPreVisit.
end(); it != ei; ++it) {
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define STAT_COUNTER(VARNAME, DESC)
static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD)
Returns true if the given C++ class is a container or iterator.
static bool wasDifferentDeclUsedForInlining(CallEventRef<> Call, const StackFrame *calleeCtx)
static std::pair< const Stmt *, const CFGBlock * > getLastStmt(const ExplodedNode *Node)
static bool isTrivialObjectAssignment(const CallEvent &Call)
static bool isCXXSharedPtrDtor(const FunctionDecl *FD)
Returns true if the given function is the destructor of a class named "shared_ptr".
static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD, StringRef Name)
Returns true if the given C++ class contains a member with the given name.
static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy, StoreManager &StoreMgr)
Adjusts a return value when the called function's return type does not match the caller's expression ...
static bool isContainerMethod(const ASTContext &Ctx, const FunctionDecl *FD)
Returns true if the given function refers to a method of a C++ container or iterator.
static unsigned getElementCountOfArrayBeingDestructed(const CallEvent &Call, const ProgramStateRef State, SValBuilder &SVB)
static ProgramStateRef getInlineFailedState(ProgramStateRef State, const Expr *CallE)
#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.
a trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
DeclarationNameTable DeclarationNames
const LangOptions & getLangOpts() const
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
AnalysisDeclContext * getContext(const Decl *D)
AnalysisDeclContext contains the context data for the function, method or block under analysis.
const Decl * getDecl() const
static bool isInStdNamespace(const Decl *D)
ASTContext & getASTContext() const
bool isBodyAutosynthesized() const
const StackFrame * getStackFrame(LocationContext const *ParentLC, const void *Data, const Expr *E, const CFGBlock *Blk, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
CFG::BuildOptions & getCFGBuildOptions()
Stores options for the analyzer from the command line.
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const
Returns the option controlling which C++ member functions will be considered for inlining.
IPAKind getIPAMode() const
Returns the inter-procedural analysis mode.
CTUPhase1InliningKind getCTUPhase1Inlining() const
unsigned InlineMaxStackDepth
The inlining stack depth limit.
Represents a single basic block in a source-level CFG.
succ_iterator succ_begin()
unsigned succ_size() const
Represents C++ constructor call.
std::optional< T > getAs() const
Convert to the specified CFGElement type, returning std::nullopt if this CFGElement is not of the des...
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
unsigned size() const
Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlockIDs()...
bool isLinear() const
Returns true if the CFG has no branches.
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
Represents a call to a C++ constructor.
CXXConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool hasMemberName(DeclarationName N) const
Determine whether this class has a member with the given name, possibly in a non-dependent base class...
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
Represents a point when we begin processing an inlined call.
const StackFrame * getCalleeContext() const
const CFGBlock * getEntry() const
Returns the entry block in the CFG for the entered function.
Represents a point when we finish the call exit sequence (for inlined call).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
ConstructionContext's subclasses describe different ways of constructing an object in C++.
Decl - This represents one declaration (or definition), e.g.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
This is a meta program point, which should be skipped by all the diagnostic reasoning etc.
This represents one expression.
Represents a function declaration or definition.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
const Decl * getDecl() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const LocationContext * getParent() const
It might return null.
const StackFrame * getStackFrame() const
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a parameter to a function.
@ PostStmtPurgeDeadSymbolsKind
const StackFrame * getStackFrame() const
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
It represents a stack frame of the call stack (based on CallEvent).
unsigned getIndex() const
const Expr * getCallSite() const
const CFGBlock * getCallSiteBlock() const
Stmt - This represents one statement.
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjCObjectPointerType() const
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
AnalyzerOptions & options
Represents a call to a C++ constructor.
const CXXConstructorDecl * getDecl() const override
Returns the declaration of the function or method that will be called.
const CXXConstructExpr * getOriginExpr() const override
Returns the expression whose value will be the result of this call.
Represents a non-static C++ member function call, no matter how it is written.
const FunctionDecl * getDecl() const override
Returns the declaration of the function or method that will be called.
Manages the lifetime of CallEvent objects.
CallEventRef getCaller(const StackFrame *CalleeSF, ProgramStateRef State)
Gets an outside caller given a callee context.
CallEventRef getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
Represents an abstract call to a function or method along a particular path.
CallEventRef< T > cloneWithState(ProgramStateRef NewState) const
Returns a copy of this CallEvent, but using the given state.
static QualType getDeclaredResultType(const Decl *D)
Returns the result type of a function or method declaration.
static bool isVariadic(const Decl *D)
Returns true if the given decl is known to be variadic.
void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)
Run checkers for pre-visiting function calls (including methods, constructors, destructors etc.
void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &CE, ExprEngine &Eng, const EvalCallOptions &CallOpts)
Run checkers for evaluating a call.
void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
void runCheckersForNewAllocator(const CXXAllocatorCall &Call, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, bool wasInlined=false)
Run checkers between C++ operator new and constructor calls.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting function calls (including methods, constructors, destructors etc.
WorkList * getCTUWorkList() const
WorkList * getWorkList() const
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void insert(ExplodedNode *N)
ImplTy::iterator iterator
const ProgramStateRef & getState() const
pred_iterator pred_begin()
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 ...
const LocationContext * getLocationContext() const
std::optional< T > getLocationAs() const &
ExplodedNode * getFirstPred()
const StackFrame * getStackFrame() const
ProgramStateManager & getStateManager()
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.
std::pair< ProgramStateRef, SVal > handleConstructionContext(const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, const LocationContext *LCtx, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)
A convenient wrapper around computeObjectUnderConstruction and updateObjectsUnderConstruction.
void removeDeadOnEndOfFunction(ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
void processCallEnter(CallEnter CE, ExplodedNode *Pred)
Generate the entry node of the callee.
void processCallExit(ExplodedNode *Pred)
Generate the sequence of nodes that simulate the call exit and the post visit for CallExpr.
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,...
CFGElement getCurrentCFGElement()
Return the CFG element corresponding to the worklist element that is currently being processed by Exp...
@ Inline_Minimal
Do minimal inlining of callees.
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.
void setCurrLocationContextAndBlock(const LocationContext *LC, const CFGBlock *B)
static std::optional< unsigned > getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retrieves which element is being constructed in a non-POD type array.
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 evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, const CallEvent &Call)
Evaluate a call, running pre- and post-call checkers and allowing checkers to be responsible for hand...
ConstCFGElementRef getCFGElementRef() const
static std::optional< unsigned > getPendingArrayDestruction(ProgramStateRef State, const LocationContext *LCtx)
Retrieves which element is being destructed in a non-POD type array.
void resetCurrLocationContextAndBlock()
CheckerManager & getCheckerManager() const
void processBeginOfFunction(ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L)
Called by CoreEngine.
ProgramStateRef bindReturnValue(const CallEvent &Call, const LocationContext *LCtx, ProgramStateRef State)
Create a new state in which the call return value is binded to the call origin expression.
unsigned getNumVisitedCurrent() const
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
AnalysisManager & getAnalysisManager()
const CFGBlock * getCurrBlock() const
Get the 'current' CFGBlock corresponding to the current work item (elementary analysis step handled b...
static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const LocationContext *LCtx)
Retrieves the size of the array in the pending ArrayInitLoopExpr.
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
This is the simplest builder which generates nodes in the ExplodedGraph.
void takeNodes(const ExplodedNodeSet &S)
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false)
Generates a node in the ExplodedGraph.
Represents any expression that calls an Objective-C method.
CallEventManager & getCallEventManager()
Information about invalidation for a particular region/symbol.
@ TK_DoNotInvalidateSuperRegion
void setTrait(SymbolRef Sym, InvalidationKinds IK)
Defines the runtime definition of the called function.
const MemRegion * getDispatchRegion()
When other definitions are possible, returns the region whose runtime type determines the method defi...
bool mayHaveOtherDefinitions()
Check if the definition we have is precise.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
QualType getType(const ASTContext &) const
Try to get a reasonable type for the given value.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
virtual void enqueue(const WorkListUnit &U)=0
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getRegion() const
Get the underlining region.
@ PSK_EscapeOutParameters
Escape for a new symbol that was generated into a region that the analyzer cannot follow during a con...
DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB, QualType Ty)
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
ProgramStateRef setDynamicExtent(ProgramStateRef State, const MemRegion *MR, DefinedOrUnknownSVal Extent)
Set the dynamic extent Extent of the region MR.
@ CE_CXXInheritedConstructor
DefinedOrUnknownSVal getElementExtent(QualType Ty, SValBuilder &SVB)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CFGBlock::ConstCFGElementRef ConstCFGElementRef
@ IPAK_DynamicDispatch
Enable inlining of dynamically dispatched methods.
@ IPAK_DynamicDispatchBifurcate
Enable inlining of dynamically dispatched methods, bifurcate paths when exact type info is unavailabl...
@ CIMK_Destructors
Refers to destructors (implicit or explicit).
@ CIMK_MemberFunctions
Refers to regular member function and operator calls.
@ CIMK_Constructors
Refers to constructors (implicit or explicit).
U cast(CodeGen::Address addr)
Hints for figuring out if a call should be inlined during evalCall().
bool IsTemporaryLifetimeExtendedViaAggregate
This call is a constructor for a temporary that is lifetime-extended by binding it to a reference-typ...
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...
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...
Traits for storing the call processing policy inside GDM.