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(), CalleeCtx);
292 State = State->killBinding(ThisVal);
298 if (
const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
300 SVal V = State->getSVal(RS, LCtx);
306 if (!ReturnedTy.
isNull()) {
307 if (
const Expr *Ex = dyn_cast<Expr>(CE)) {
314 State = State->BindExpr(CE, CallerCtx,
V);
320 svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), CalleeCtx);
322 ThisV = State->getSVal(ThisV.
castAs<
Loc>());
323 State = State->BindExpr(CCE, CallerCtx, ThisV);
325 ShouldRepeatCall = shouldRepeatCtorCall(State, CCE, CallerCtx);
328 if (
const auto *CNE = dyn_cast<CXXNewExpr>(CE)) {
334 SVal AllocV = State->getSVal(CNE, CallerCtx);
335 AllocV = svalBuilder.evalCast(
339 State = addObjectUnderConstruction(State, CNE, CalleeCtx->
getParent(),
344 if (!ShouldRepeatCall) {
345 State = removeStateTraitsUsedForArrayEvaluation(
346 State, dyn_cast_or_null<CXXConstructExpr>(CE), CallerCtx);
355 if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
360 nullptr, &RetValBind)};
368 BoundRetNode, CleanedNodes,
nullptr, CalleeCtx,
372 CleanedNodes.
insert(CEBNode);
403 if (llvm::isa_and_nonnull<CXXNewExpr>(CE)) {
410 DstPostCall.
insert(DstPostPostCallCallback);
420 AMgr.getAnalyzerOptions().MayInlineCXXAllocator)) {
429 unsigned Idx = CalleeCtx->
getIndex() + (ShouldRepeatCall ? 0 : 1);
449 return Cfg->
size() >= AMgr.
options.MinCFGSizeTreatFunctionsAsLarge;
457void ExprEngine::examineStackFrames(
const Decl *D,
const LocationContext *LCtx,
458 bool &IsRecursive,
unsigned &StackDepth) {
463 if (
const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LCtx)) {
464 const Decl *DI = SFC->getDecl();
476 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI);
477 if (!isSmall(CalleeADC))
491 enum DynamicDispatchMode {
492 DynamicDispatchModeInlined = 1,
493 DynamicDispatchModeConservative
505 if (
Call.isForeign() && !isSecondPhaseCTU()) {
514 const bool BState = State->get<CTUDispatchBifurcation>();
519 ConservativeEvalState = State->set<CTUDispatchBifurcation>(
true);
520 conservativeEvalCall(
Call, Bldr, Pred, ConservativeEvalState);
522 conservativeEvalCall(
Call, Bldr, Pred, State);
536 const LocationContext *ParentOfCallee = CallerSFC;
540 assert(BR &&
"If we have the block definition we should have its region");
541 AnalysisDeclContext *BlockCtx = AMgr.getAnalysisDeclContext(D);
548 const Expr *CallE =
Call.getOriginExpr();
551 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
552 const StackFrameContext *CalleeSFC =
556 CallEnter Loc(CallE, CalleeSFC, CurLC);
560 State = State->enterStackFrame(
Call, CalleeSFC);
563 if (ExplodedNode *N = G.getNode(Loc, State,
false, &isNew)) {
564 N->addPredecessor(Pred, G);
574 Engine.FunctionSummaries->bumpNumTimesInlined(D);
583 if (!isSecondPhaseCTU())
586 VisitedCallees->insert(D);
595 assert(ReplayState == CallE &&
"Backtracked to the wrong call.");
617 evalCall(dstCallEvaluated, N, *CallTemplate);
632 const Expr *E =
Call.getOriginExpr();
639 for (
unsigned CallI = 0, CallN =
Call.getNumArgs(); CallI != CallN; ++CallI) {
640 unsigned I =
Call.getASTArgumentIndex(CallI);
645 ->getStackFrame()->getParent()
647 State = finishObjectConstruction(State, {E, I}, LC);
661 if (CleanedState == State) {
666 const Expr *E =
Call.getOriginExpr();
667 const LocationContext *LC =
Call.getLocationContext();
668 NodeBuilder B(Pred, Dst, *currBldrCtx);
669 static SimpleProgramPointTag
Tag(
"ExprEngine",
670 "Finish argument construction");
671 PreStmt PP(E, LC, &Tag);
672 B.generateNode(PP, CleanedState, Pred);
692 dstCallEvaluated, dstPreVisit, CallTemplate, *
this,
EvalCallOptions());
698 finishArgumentConstruction(dstArgumentCleanup, I, CallTemplate);
702 CallTemplate, *
this);
727 if (
const MemRegion *MR =
Call->getArgSVal(Arg).getAsRegion())
735 if (State == I->getState())
745 const Expr *E =
Call.getOriginExpr();
752 switch (Msg->getMethodFamily()) {
759 return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
763 SVal ThisV =
C->getCXXThisVal();
764 ThisV = State->getSVal(ThisV.
castAs<
Loc>());
765 return State->BindExpr(E, LCtx, ThisV);
774 assert(RTC->getStmt() ==
Call.getOriginExpr());
777 Call.getOriginExpr(), State, currBldrCtx, LCtx,
778 RTC->getConstructionContext(), CallOpts);
789 State = State->invalidateRegions(TargetR, Elem, Count, LCtx,
799 const auto *CNE = dyn_cast<CXXNewExpr>(E);
800 if (CNE && CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
801 R = svalBuilder.getConjuredHeapSymbolVal(Elem, LCtx, 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, LCtx);
809 ElementCount = svalBuilder.makeIntVal(1,
true);
815 svalBuilder.evalBinOp(State, BO_Mul, ElementCount, ElementSize,
816 svalBuilder.getArrayIndexType());
825 R = svalBuilder.conjureSymbolVal(Elem, LCtx, ResultTy, Count);
828 return State->BindExpr(E, LCtx, R);
843ExprEngine::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, CurLC))
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;
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 LocationContext *LCtx) {
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 LocationContext *LCtx) {
1191 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty)) {
1224 performTrivialCopy(Bldr, Pred,
Call);
1231 const Expr *E =
Call.getOriginExpr();
1234 if (InlinedFailedState) {
1236 State = InlinedFailedState;
1241 if (shouldInlineCall(
Call, D, Pred, CallOpts)) {
1253 conservativeEvalCall(
Call, Bldr, Pred, State);
1257 ctuBifurcate(
Call, D, Bldr, Pred, State);
1264 State = removeStateTraitsUsedForArrayEvaluation(
1265 State, dyn_cast_or_null<CXXConstructExpr>(E),
Call.getLocationContext());
1268 conservativeEvalCall(
Call, Bldr, Pred, State);
1271void ExprEngine::BifurcateCall(
const MemRegion *BifurReg,
1280 const unsigned *BState =
1281 State->get<DynamicDispatchBifurcationMap>(BifurReg);
1284 if (*BState == DynamicDispatchModeInlined)
1285 ctuBifurcate(
Call, D, Bldr, Pred, State);
1289 conservativeEvalCall(
Call, Bldr, Pred, State);
1296 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1297 DynamicDispatchModeInlined);
1298 ctuBifurcate(
Call, D, Bldr, Pred, IState);
1301 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1302 DynamicDispatchModeConservative);
1303 conservativeEvalCall(
Call, Bldr, Pred, NoIState);
1305 NumOfDynamicDispatchPathSplits++;
1317 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 ProgramStateRef getInlineFailedState(ProgramStateRef State, const Stmt *CallE)
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 bool wasDifferentDeclUsedForInlining(CallEventRef<> Call, const StackFrameContext *calleeCtx)
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)
#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 BlockInvocationContext * getBlockInvocationContext(const LocationContext *ParentLC, const BlockDecl *BD, const void *Data)
Obtain a context of the block invocation using its parent context.
const Decl * getDecl() const
static bool isInStdNamespace(const Decl *D)
const StackFrameContext * getStackFrame(LocationContext const *ParentLC, const Stmt *S, const CFGBlock *Blk, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
ASTContext & getASTContext() const
bool isBodyAutosynthesized() const
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 CFGBlock * getEntry() const
Returns the entry block in the CFG for the entered function.
const StackFrameContext * getCalleeContext() const
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.
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
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 StackFrameContext * 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 Stmt * 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 getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx, CFGBlock::ConstCFGElementRef ElemRef)
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
Gets an outside caller given a callee context.
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 StackFrameContext * getStackFrame() const
const LocationContext * getLocationContext() const
std::optional< T > getLocationAs() const &
ExplodedNode * getFirstPred()
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)
Retreives 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)
Retreives 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)
Retreives 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 of 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.