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->getCalleeStackFrame()->getCallSite();
100 std::optional<CallEnter> CE;
105 CE->getCalleeStackFrame() != CEE->getCalleeStackFrame());
113 if (CE->getCalleeStackFrame() == SF)
118 return std::make_pair(
nullptr,
nullptr);
123 return std::make_pair(S, Blk);
140 if (ExpectedTy == ActualTy)
169 const Stmt *LastSt =
nullptr;
172 if (!Blk || !LastSt) {
182 removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt), SF,
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();
225 ProgramStateRef State,
const CXXConstructExpr *E,
const StackFrame *SF) {
227 assert(SF &&
"Stack frame must be provided!");
231 State = removePendingInitLoop(State, E, SF);
234 State = removeIndexOfElementToConstruct(State, E, SF);
238 State = removePendingArrayDestruction(State, SF);
265 isa_and_nonnull<ReturnStmt>(LastSt) ? Blk : &CEBNode->
getCFG().
getExit();
281 bool ShouldRepeatCall =
false;
283 if (
const auto *DtorDecl =
284 dyn_cast_or_null<CXXDestructorDecl>(
Call->getDecl())) {
286 ShouldRepeatCall = *Idx > 0;
288 auto ThisVal = svalBuilder.getCXXThis(DtorDecl->getParent(), CalleeSF);
289 State = State->killBinding(ThisVal);
295 if (
const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
299 if (RS->getRetValue())
300 V = State->getSVal(RS->getRetValue(), SF);
306 if (!ReturnedTy.
isNull()) {
312 State = State->BindExpr(CE, CallerSF,
V);
318 svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), CalleeSF);
320 ThisV = State->getSVal(ThisV.
castAs<
Loc>());
321 State = State->BindExpr(CCE, CallerSF, ThisV);
323 ShouldRepeatCall = shouldRepeatCtorCall(State, CCE, CallerSF);
326 if (
const auto *CNE = dyn_cast<CXXNewExpr>(CE)) {
332 SVal AllocV = State->getSVal(CNE, CallerSF);
333 AllocV = svalBuilder.evalCast(
338 addObjectUnderConstruction(State, CNE, CalleeSF->
getParent(), AllocV);
342 if (!ShouldRepeatCall) {
343 State = removeStateTraitsUsedForArrayEvaluation(
344 State, dyn_cast_or_null<CXXConstructExpr>(CE), CallerSF);
353 if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
358 nullptr, &RetValBind)};
365 removeDead(BoundRetNode, CleanedNodes,
nullptr, CalleeSF,
369 CleanedNodes.
insert(CEBNode);
400 if (llvm::isa_and_nonnull<CXXNewExpr>(CE)) {
407 DstPostCall.
insert(DstPostPostCallCallback);
417 AMgr.getAnalyzerOptions().MayInlineCXXAllocator)) {
426 unsigned Idx = CalleeSF->
getIndex() + (ShouldRepeatCall ? 0 : 1);
445 return Cfg->
size() >= AMgr.
options.MinCFGSizeTreatFunctionsAsLarge;
453void ExprEngine::examineStackFrames(
const Decl *D,
const StackFrame *SF,
454 bool &IsRecursive,
unsigned &StackDepth) {
471 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI);
472 if (!isSmall(CalleeADC))
485 enum DynamicDispatchMode {
486 DynamicDispatchModeInlined = 1,
487 DynamicDispatchModeConservative
498 if (
Call.isForeign() && !isSecondPhaseCTU()) {
507 const bool BState = State->get<CTUDispatchBifurcation>();
512 State = State->set<CTUDispatchBifurcation>(
true);
514 Dst.
insert(conservativeEvalCall(
Call, Pred, State));
526 const BlockDataRegion *BlockInvocationData =
nullptr;
530 assert(BlockInvocationData &&
531 "If we have the block definition we should have its region");
535 const Expr *CallE =
Call.getOriginExpr();
538 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
543 CallEnter Loc(CallE, CalleeSF, CallerSF);
547 State = State->enterStackFrame(
Call, CalleeSF);
550 if (ExplodedNode *N = G.getNode(Loc, State,
false, &isNew)) {
551 N->addPredecessor(Pred, G);
557 Engine.FunctionSummaries->bumpNumTimesInlined(D);
566 if (!isSecondPhaseCTU())
569 VisitedCallees->insert(D);
578 assert(ReplayState == CallE &&
"Backtracked to the wrong call.");
586 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
590 const Decl *Callee = OCE->getCalleeDecl();
591 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
592 if (MD->isImplicitObjectMemberFunction()) {
596 createTemporaryRegionIfNeeded(State, SF, OCE->getArg(0));
597 if (NewState != State) {
599 Pred = Engine.makeNode(PS, NewState, Pred);
620 evalCall(dstCallEvaluated, N, *CallTemplate);
635 const Expr *E =
Call.getOriginExpr();
642 for (
unsigned CallI = 0, CallN =
Call.getNumArgs(); CallI != CallN; ++CallI) {
643 unsigned I =
Call.getASTArgumentIndex(CallI);
649 ->getParent() == SF);
650 State = finishObjectConstruction(State, {E, I}, SF);
664 if (CleanedState == State) {
669 const Expr *E =
Call.getOriginExpr();
670 const StackFrame *SF =
Call.getStackFrame();
671 static SimpleProgramPointTag
Tag(
"ExprEngine",
672 "Finish argument construction");
673 Dst.
insert(Engine.makeNode(PreStmt(E, SF, &Tag), CleanedState, Pred));
693 dstCallEvaluated, dstPreVisit, CallTemplate, *
this,
EvalCallOptions());
699 finishArgumentConstruction(dstArgumentCleanup, I, CallTemplate);
703 CallTemplate, *
this);
727 if (
const MemRegion *MR =
Call->getArgSVal(Arg).getAsRegion())
735 if (State != I->getState())
736 I = Engine.makeNode(I->getLocation(), State, I);
745 const Expr *E =
Call.getOriginExpr();
752 switch (Msg->getMethodFamily()) {
759 return State->BindExpr(E, SF, Msg->getReceiverSVal());
763 SVal ThisV =
C->getCXXThisVal();
764 ThisV = State->getSVal(ThisV.
castAs<
Loc>());
765 return State->BindExpr(E, SF, ThisV);
774 assert(RTC->getStmt() ==
Call.getOriginExpr());
778 RTC->getConstructionContext(), CallOpts);
789 State = State->invalidateRegions(TargetR, Elem, Count, SF,
799 const auto *CNE = dyn_cast<CXXNewExpr>(E);
800 if (CNE && CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
801 R = svalBuilder.getConjuredHeapSymbolVal(Elem, SF, E->
getType(), Count);
802 const MemRegion *MR = R.getAsRegion()->StripCasts();
806 if (
const Expr *SizeExpr = CNE->getArraySize().value_or(
nullptr)) {
807 ElementCount = State->getSVal(SizeExpr, SF);
809 ElementCount = svalBuilder.makeIntVal(1,
true);
815 svalBuilder.evalBinOp(State, BO_Mul, ElementCount, ElementSize,
816 svalBuilder.getArrayIndexType());
825 R = svalBuilder.conjureSymbolVal(Elem, SF, ResultTy, Count);
828 return State->BindExpr(E, SF, R);
841 return Engine.
makeNode(
Call.getProgramPoint(
false, &PT), State, Pred);
844ExprEngine::CallInlinePolicy
849 switch (
Call.getKind()) {
857 return CIP_DisallowedAlways;
861 return CIP_DisallowedAlways;
871 if (llvm::isa_and_nonnull<NewAllocatedObjectConstructionContext>(CC) &&
872 !Opts.MayInlineCXXAllocator)
873 return CIP_DisallowedOnce;
876 if (!shouldInlineArrayConstruction(Pred->
getState(), CtorExpr, CallerSF))
877 return CIP_DisallowedOnce;
892 return CIP_DisallowedAlways;
898 !Opts.ShouldIncludeTemporaryDtorsInCFG)
899 return CIP_DisallowedOnce;
905 return CIP_DisallowedOnce;
910 return CIP_DisallowedOnce;
922 return CIP_DisallowedAlways;
932 return CIP_DisallowedOnce;
938 !Opts.MayInlineCXXTemporaryDtors)
939 return CIP_DisallowedOnce;
945 return CIP_DisallowedOnce;
951 if (Opts.MayInlineCXXAllocator)
955 return CIP_DisallowedAlways;
957 if (!Opts.MayInlineObjCMethod)
958 return CIP_DisallowedAlways;
961 return CIP_DisallowedAlways;
1006 if (II->isStr(
"shared_ptr"))
1017bool ExprEngine::mayInlineDecl(AnalysisDeclContext *CalleeADC)
const {
1018 AnalyzerOptions &Opts = AMgr.getAnalyzerOptions();
1026 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeADC->
getDecl())) {
1028 if (!Opts.MayInlineTemplateFunctions)
1033 if (!Opts.MayInlineCXXStandardLibrary)
1040 if (!Opts.MayInlineCXXContainerMethods)
1041 if (!AMgr.isInCodeFile(FD->getLocation()))
1049 if (!Opts.MayInlineCXXSharedPtrDtor)
1057 const CFG *CalleeCFG = CalleeADC->
getCFG();
1062 if (isHuge(CalleeADC))
1067 if (!CalleeADC->
getAnalysis<RelaxedLiveVariables>())
1073bool ExprEngine::shouldInlineCall(
const CallEvent &
Call,
const Decl *D,
1080 AnalyzerOptions &Opts = AMgr.options;
1081 AnalysisDeclContextManager &ADCMgr = AMgr.getAnalysisDeclContextManager();
1082 AnalysisDeclContext *CalleeADC = ADCMgr.
getContext(D);
1090 if (!AMgr.shouldInlineCall())
1094 std::optional<bool> MayInline = Engine.FunctionSummaries->mayInline(D);
1102 if (mayInlineDecl(CalleeADC)) {
1103 Engine.FunctionSummaries->markMayInline(D);
1105 Engine.FunctionSummaries->markShouldNotInline(D);
1114 CallInlinePolicy CIP = mayInlineCallKind(
Call, Pred, Opts, CallOpts);
1115 if (CIP != CIP_Allowed) {
1116 if (CIP == CIP_DisallowedAlways) {
1117 assert(!MayInline || *MayInline);
1118 Engine.FunctionSummaries->markShouldNotInline(D);
1124 bool IsRecursive =
false;
1125 unsigned StackDepth = 0;
1126 examineStackFrames(D, Pred->
getStackFrame(), IsRecursive, StackDepth);
1128 (!isSmall(CalleeADC) || IsRecursive))
1132 if ((Engine.FunctionSummaries->getNumTimesInlined(D) >
1133 Opts.MaxTimesInlineLarge) &&
1134 isLarge(CalleeADC)) {
1135 NumReachedInlineCountMax++;
1139 if (HowToInline ==
Inline_Minimal && (!isSmall(CalleeADC) || IsRecursive))
1145bool ExprEngine::shouldInlineArrayConstruction(
const ProgramStateRef State,
1146 const CXXConstructExpr *CE,
1147 const StackFrame *SF) {
1152 if (
const auto *CAT = dyn_cast<ConstantArrayType>(CE->
getType())) {
1163 return shouldInlineArrayDestruction(ArrSize);
1168 return shouldInlineArrayDestruction(*Size);
1173bool ExprEngine::shouldInlineArrayDestruction(uint64_t Size) {
1175 uint64_t maxAllowedSize = AMgr.options.maxBlockVisitOnPath;
1178 return Size <= maxAllowedSize && Size > 0;
1182 const CXXConstructExpr *E,
1183 const StackFrame *SF) {
1191 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty)) {
1224 performTrivialCopy(Dst, Pred,
Call);
1228 const Expr *E =
Call.getOriginExpr();
1231 if (InlinedFailedState) {
1233 State = InlinedFailedState;
1238 if (shouldInlineCall(
Call, D, Pred, CallOpts)) {
1250 Dst.
insert(conservativeEvalCall(
Call, Pred, State));
1254 ctuBifurcate(
Call, D, Dst, Pred, State);
1261 State = removeStateTraitsUsedForArrayEvaluation(
1262 State, dyn_cast_or_null<CXXConstructExpr>(E),
Call.getStackFrame());
1265 Dst.
insert(conservativeEvalCall(
Call, Pred, State));
1268void ExprEngine::dynDispatchBifurcate(
const MemRegion *BifurReg,
1278 const unsigned *BState =
1279 State->get<DynamicDispatchBifurcationMap>(BifurReg);
1282 if (*BState == DynamicDispatchModeInlined)
1283 ctuBifurcate(
Call, D, Dst, Pred, State);
1287 Dst.
insert(conservativeEvalCall(
Call, Pred, State));
1294 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1295 DynamicDispatchModeInlined);
1296 ctuBifurcate(
Call, D, Dst, Pred, IState);
1299 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1300 DynamicDispatchModeConservative);
1301 Dst.
insert(conservativeEvalCall(
Call, Pred, NoIState));
1303 NumOfDynamicDispatchPathSplits++;
1313 Dst.
insert(Engine.makePostStmtNode(RS, N->getState(), N));
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(const StackFrame *ParentSF, 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 * getCalleeStackFrame() 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.
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.
unsigned getIndex() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const Expr * getCallSite() const
const Decl * getDecl() const
const StackFrame * getParent() const
It might return null.
const CFGBlock * getCallSiteBlock() const
Stmt - This represents one statement.
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
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 StackFrame *SF, 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
ExplodedNode * makeNode(const ProgramPoint &Loc, ProgramStateRef State, ExplodedNode *Pred, bool MarkAsSink=false) const
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void insert(ExplodedNode *N)
const ProgramStateRef & getState() const
pred_iterator pred_begin()
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 ...
std::optional< T > getLocationAs() const &
ExplodedNode * getFirstPred()
const StackFrame * getStackFrame() const
ProgramStateManager & getStateManager()
void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out, const Stmt *ReferenceStmt, const StackFrame *SF, const Stmt *DiagnosticStmt=nullptr, ProgramPoint::Kind K=ProgramPoint::PreStmtPurgeDeadSymbolsKind)
Run the analyzer's garbage collection - remove dead symbols and bindings from the state.
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.
CFGElement getCurrentCFGElement()
Return the CFG element corresponding to the worklist element that is currently being processed by Exp...
static std::optional< unsigned > getIndexOfElementToConstruct(ProgramStateRef State, const CXXConstructExpr *E, const StackFrame *SF)
Retrieves which element is being constructed in a non-POD type array.
@ Inline_Minimal
Do minimal inlining of callees.
ProgramStateRef bindReturnValue(const CallEvent &Call, const StackFrame *SF, ProgramStateRef State)
Create a new state in which the call return value is binded to the call origin expression.
static std::optional< unsigned > getPendingInitLoop(ProgramStateRef State, const CXXConstructExpr *E, const StackFrame *SF)
Retrieves the size of the array in the pending ArrayInitLoopExpr.
void setCurrStackFrameAndBlock(const StackFrame *SF, const CFGBlock *B)
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...
void defaultEvalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
ConstCFGElementRef getCFGElementRef() const
static std::optional< unsigned > getPendingArrayDestruction(ProgramStateRef State, const StackFrame *SF)
Retrieves which element is being destructed in a non-POD type array.
ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State, ArrayRef< std::pair< SVal, SVal > > LocAndVals, const StackFrame *SF, PointerEscapeKind Kind, const CallEvent *Call)
Call PointerEscape callback when a value escapes as a result of bind.
CheckerManager & getCheckerManager() const
static std::optional< SVal > getObjectUnderConstruction(ProgramStateRef State, const ConstructionContextItem &Item, const StackFrame *SF)
By looking at a certain item that may be potentially part of an object's ConstructionContext,...
void processBeginOfFunction(ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L)
Called by CoreEngine.
unsigned getNumVisitedCurrent() const
AnalysisManager & getAnalysisManager()
std::pair< ProgramStateRef, SVal > handleConstructionContext(const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, const StackFrame *SF, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)
A convenient wrapper around computeObjectUnderConstruction and updateObjectsUnderConstruction.
void resetCurrStackFrameAndBlock()
const CFGBlock * getCurrBlock() const
Get the 'current' CFGBlock corresponding to the current work item (elementary analysis step handled b...
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
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.