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
499 if (
Call.isForeign() && !isSecondPhaseCTU()) {
508 const bool BState = State->get<CTUDispatchBifurcation>();
513 ConservativeEvalState = State->set<CTUDispatchBifurcation>(
true);
514 conservativeEvalCall(
Call, Bldr, Pred, ConservativeEvalState);
516 conservativeEvalCall(
Call, Bldr, Pred, State);
529 const BlockDataRegion *BlockInvocationData =
nullptr;
533 assert(BlockInvocationData &&
534 "If we have the block definition we should have its region");
538 const Expr *CallE =
Call.getOriginExpr();
541 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
546 CallEnter Loc(CallE, CalleeSF, CallerSF);
550 State = State->enterStackFrame(
Call, CalleeSF);
553 if (ExplodedNode *N = G.getNode(Loc, State,
false, &isNew)) {
554 N->addPredecessor(Pred, G);
564 Engine.FunctionSummaries->bumpNumTimesInlined(D);
573 if (!isSecondPhaseCTU())
576 VisitedCallees->insert(D);
585 assert(ReplayState == CallE &&
"Backtracked to the wrong call.");
593 if (
const auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
597 const Decl *Callee = OCE->getCalleeDecl();
598 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(Callee)) {
599 if (MD->isImplicitObjectMemberFunction()) {
603 createTemporaryRegionIfNeeded(State, SF, OCE->getArg(0));
604 if (NewState != State) {
606 Pred = Engine.makeNode(PS, NewState, Pred);
627 evalCall(dstCallEvaluated, N, *CallTemplate);
642 const Expr *E =
Call.getOriginExpr();
649 for (
unsigned CallI = 0, CallN =
Call.getNumArgs(); CallI != CallN; ++CallI) {
650 unsigned I =
Call.getASTArgumentIndex(CallI);
656 ->getParent() == SF);
657 State = finishObjectConstruction(State, {E, I}, SF);
671 if (CleanedState == State) {
676 const Expr *E =
Call.getOriginExpr();
677 const StackFrame *SF =
Call.getStackFrame();
678 static SimpleProgramPointTag
Tag(
"ExprEngine",
679 "Finish argument construction");
680 Dst.
insert(Engine.makeNode(PreStmt(E, SF, &Tag), CleanedState, Pred));
700 dstCallEvaluated, dstPreVisit, CallTemplate, *
this,
EvalCallOptions());
706 finishArgumentConstruction(dstArgumentCleanup, I, CallTemplate);
710 CallTemplate, *
this);
734 if (
const MemRegion *MR =
Call->getArgSVal(Arg).getAsRegion())
742 if (State != I->getState())
743 I = Engine.makeNode(I->getLocation(), State, I);
752 const Expr *E =
Call.getOriginExpr();
759 switch (Msg->getMethodFamily()) {
766 return State->BindExpr(E, SF, Msg->getReceiverSVal());
770 SVal ThisV =
C->getCXXThisVal();
771 ThisV = State->getSVal(ThisV.
castAs<
Loc>());
772 return State->BindExpr(E, SF, ThisV);
781 assert(RTC->getStmt() ==
Call.getOriginExpr());
785 RTC->getConstructionContext(), CallOpts);
796 State = State->invalidateRegions(TargetR, Elem, Count, SF,
806 const auto *CNE = dyn_cast<CXXNewExpr>(E);
807 if (CNE && CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
808 R = svalBuilder.getConjuredHeapSymbolVal(Elem, SF, E->
getType(), Count);
809 const MemRegion *MR = R.getAsRegion()->StripCasts();
813 if (
const Expr *SizeExpr = CNE->getArraySize().value_or(
nullptr)) {
814 ElementCount = State->getSVal(SizeExpr, SF);
816 ElementCount = svalBuilder.makeIntVal(1,
true);
822 svalBuilder.evalBinOp(State, BO_Mul, ElementCount, ElementSize,
823 svalBuilder.getArrayIndexType());
832 R = svalBuilder.conjureSymbolVal(Elem, SF, ResultTy, Count);
835 return State->BindExpr(E, SF, R);
850ExprEngine::CallInlinePolicy
855 switch (
Call.getKind()) {
863 return CIP_DisallowedAlways;
867 return CIP_DisallowedAlways;
877 if (llvm::isa_and_nonnull<NewAllocatedObjectConstructionContext>(CC) &&
878 !Opts.MayInlineCXXAllocator)
879 return CIP_DisallowedOnce;
882 if (!shouldInlineArrayConstruction(Pred->
getState(), CtorExpr, CallerSF))
883 return CIP_DisallowedOnce;
898 return CIP_DisallowedAlways;
904 !Opts.ShouldIncludeTemporaryDtorsInCFG)
905 return CIP_DisallowedOnce;
911 return CIP_DisallowedOnce;
916 return CIP_DisallowedOnce;
928 return CIP_DisallowedAlways;
938 return CIP_DisallowedOnce;
944 !Opts.MayInlineCXXTemporaryDtors)
945 return CIP_DisallowedOnce;
951 return CIP_DisallowedOnce;
957 if (Opts.MayInlineCXXAllocator)
961 return CIP_DisallowedAlways;
963 if (!Opts.MayInlineObjCMethod)
964 return CIP_DisallowedAlways;
967 return CIP_DisallowedAlways;
1012 if (II->isStr(
"shared_ptr"))
1023bool ExprEngine::mayInlineDecl(AnalysisDeclContext *CalleeADC)
const {
1024 AnalyzerOptions &Opts = AMgr.getAnalyzerOptions();
1032 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeADC->
getDecl())) {
1034 if (!Opts.MayInlineTemplateFunctions)
1039 if (!Opts.MayInlineCXXStandardLibrary)
1046 if (!Opts.MayInlineCXXContainerMethods)
1047 if (!AMgr.isInCodeFile(FD->getLocation()))
1055 if (!Opts.MayInlineCXXSharedPtrDtor)
1063 const CFG *CalleeCFG = CalleeADC->
getCFG();
1068 if (isHuge(CalleeADC))
1073 if (!CalleeADC->
getAnalysis<RelaxedLiveVariables>())
1079bool ExprEngine::shouldInlineCall(
const CallEvent &
Call,
const Decl *D,
1086 AnalyzerOptions &Opts = AMgr.options;
1087 AnalysisDeclContextManager &ADCMgr = AMgr.getAnalysisDeclContextManager();
1088 AnalysisDeclContext *CalleeADC = ADCMgr.
getContext(D);
1096 if (!AMgr.shouldInlineCall())
1100 std::optional<bool> MayInline = Engine.FunctionSummaries->mayInline(D);
1108 if (mayInlineDecl(CalleeADC)) {
1109 Engine.FunctionSummaries->markMayInline(D);
1111 Engine.FunctionSummaries->markShouldNotInline(D);
1120 CallInlinePolicy CIP = mayInlineCallKind(
Call, Pred, Opts, CallOpts);
1121 if (CIP != CIP_Allowed) {
1122 if (CIP == CIP_DisallowedAlways) {
1123 assert(!MayInline || *MayInline);
1124 Engine.FunctionSummaries->markShouldNotInline(D);
1130 bool IsRecursive =
false;
1131 unsigned StackDepth = 0;
1132 examineStackFrames(D, Pred->
getStackFrame(), IsRecursive, StackDepth);
1134 (!isSmall(CalleeADC) || IsRecursive))
1138 if ((Engine.FunctionSummaries->getNumTimesInlined(D) >
1139 Opts.MaxTimesInlineLarge) &&
1140 isLarge(CalleeADC)) {
1141 NumReachedInlineCountMax++;
1145 if (HowToInline ==
Inline_Minimal && (!isSmall(CalleeADC) || IsRecursive))
1151bool ExprEngine::shouldInlineArrayConstruction(
const ProgramStateRef State,
1152 const CXXConstructExpr *CE,
1153 const StackFrame *SF) {
1158 if (
const auto *CAT = dyn_cast<ConstantArrayType>(CE->
getType())) {
1169 return shouldInlineArrayDestruction(ArrSize);
1174 return shouldInlineArrayDestruction(*Size);
1179bool ExprEngine::shouldInlineArrayDestruction(uint64_t Size) {
1181 uint64_t maxAllowedSize = AMgr.options.maxBlockVisitOnPath;
1184 return Size <= maxAllowedSize && Size > 0;
1188 const CXXConstructExpr *E,
1189 const StackFrame *SF) {
1197 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty)) {
1230 performTrivialCopy(Bldr, Pred,
Call);
1234 const Expr *E =
Call.getOriginExpr();
1237 if (InlinedFailedState) {
1239 State = InlinedFailedState;
1244 if (shouldInlineCall(
Call, D, Pred, CallOpts)) {
1256 conservativeEvalCall(
Call, Bldr, Pred, State);
1260 ctuBifurcate(
Call, D, Bldr, Pred, State);
1267 State = removeStateTraitsUsedForArrayEvaluation(
1268 State, dyn_cast_or_null<CXXConstructExpr>(E),
Call.getStackFrame());
1271 conservativeEvalCall(
Call, Bldr, Pred, State);
1274void ExprEngine::BifurcateCall(
const MemRegion *BifurReg,
1283 const unsigned *BState =
1284 State->get<DynamicDispatchBifurcationMap>(BifurReg);
1287 if (*BState == DynamicDispatchModeInlined)
1288 ctuBifurcate(
Call, D, Bldr, Pred, State);
1292 conservativeEvalCall(
Call, Bldr, Pred, State);
1299 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1300 DynamicDispatchModeInlined);
1301 ctuBifurcate(
Call, D, Bldr, Pred, IState);
1304 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1305 DynamicDispatchModeConservative);
1306 conservativeEvalCall(
Call, Bldr, Pred, NoIState);
1308 NumOfDynamicDispatchPathSplits++;
1320 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(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
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 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
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 ...
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...
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
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
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
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.