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");
48 assert(Entry->
empty());
67 Engine.enqueue(DstBegin);
73static std::pair<
const Stmt*,
75 const Stmt *S =
nullptr;
89 S = CEE->getCalleeContext()->getCallSite();
96 std::optional<CallEnter> CE;
100 }
while (!CE || CE->getCalleeContext() != CEE->getCalleeContext());
108 if (CE->getCalleeContext() == SF)
113 return std::make_pair(
nullptr,
nullptr);
118 return std::make_pair(S, Blk);
135 if (ExpectedTy == ActualTy)
165 const Stmt *LastSt =
nullptr;
168 if (!Blk || !LastSt) {
180 removeDead(Pred, Dst, dyn_cast<ReturnStmt>(LastSt), LCtx,
188 const Decl *StaticDecl =
Call->getDecl();
189 assert(RuntimeCallee);
200 "The call event is not a destructor call!");
204 auto ThisVal = DtorCall.getCXXThisVal();
206 if (
auto ThisElementRegion = dyn_cast<ElementRegion>(ThisVal.getAsRegion())) {
207 auto ArrayRegion = ThisElementRegion->getAsArrayOffset().getRegion();
208 auto ElementType = ThisElementRegion->getElementType();
213 if (!ElementCount.isConstant())
216 return ElementCount.getAsInteger()->getLimitedValue();
224 const LocationContext *LCtx) {
226 assert(LCtx &&
"Location context must be provided!");
230 State = removePendingInitLoop(State, E, LCtx);
233 State = removeIndexOfElementToConstruct(State, E, LCtx);
237 State = removePendingArrayDestruction(State, LCtx);
262 const Stmt *LastSt =
nullptr;
278 bool ShouldRepeatCall =
false;
280 if (
const auto *DtorDecl =
281 dyn_cast_or_null<CXXDestructorDecl>(
Call->getDecl())) {
283 ShouldRepeatCall = *Idx > 0;
285 auto ThisVal = svalBuilder.getCXXThis(DtorDecl->getParent(), calleeCtx);
286 state = state->killBinding(ThisVal);
292 if (
const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
294 SVal V = state->getSVal(RS, LCtx);
300 if (!ReturnedTy.
isNull()) {
301 if (
const Expr *Ex = dyn_cast<Expr>(CE)) {
308 state = state->BindExpr(CE, callerCtx,
V);
314 svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
316 ThisV = state->getSVal(ThisV.
castAs<
Loc>());
317 state = state->BindExpr(CCE, callerCtx, ThisV);
319 ShouldRepeatCall = shouldRepeatCtorCall(state, CCE, callerCtx);
322 if (
const auto *CNE = dyn_cast<CXXNewExpr>(CE)) {
328 SVal AllocV = state->getSVal(CNE, callerCtx);
329 AllocV = svalBuilder.evalCast(
333 state = addObjectUnderConstruction(state, CNE, calleeCtx->
getParent(),
338 if (!ShouldRepeatCall) {
339 state = removeStateTraitsUsedForArrayEvaluation(
340 state, dyn_cast_or_null<CXXConstructExpr>(CE), callerCtx);
349 if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
354 nullptr, &retValBind)};
369 removeDead(BindedRetNode, CleanedNodes,
nullptr, calleeCtx,
372 currBldrCtx =
nullptr;
374 CleanedNodes.
Add(CEBNode);
399 if (llvm::isa_and_nonnull<CXXNewExpr>(CE)) {
402 CEENode, *UpdatedCall, *
this,
421 AMgr.getAnalyzerOptions().MayInlineCXXAllocator)) {
431 unsigned Idx = calleeCtx->
getIndex() + (ShouldRepeatCall ? 0 : 1);
450 return Cfg->
size() >= AMgr.
options.MinCFGSizeTreatFunctionsAsLarge;
458void ExprEngine::examineStackFrames(
const Decl *D,
const LocationContext *LCtx,
459 bool &IsRecursive,
unsigned &StackDepth) {
464 if (
const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LCtx)) {
465 const Decl *DI = SFC->getDecl();
477 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI);
478 if (!isSmall(CalleeADC))
492 enum DynamicDispatchMode {
493 DynamicDispatchModeInlined = 1,
494 DynamicDispatchModeConservative
506 if (
Call.isForeign() && !isSecondPhaseCTU()) {
515 const bool BState = State->get<CTUDispatchBifurcation>();
520 ConservativeEvalState = State->set<CTUDispatchBifurcation>(
true);
521 conservativeEvalCall(
Call, Bldr, Pred, ConservativeEvalState);
523 conservativeEvalCall(
Call, Bldr, Pred, State);
537 const LocationContext *ParentOfCallee = CallerSFC;
541 assert(BR &&
"If we have the block definition we should have its region");
542 AnalysisDeclContext *BlockCtx = AMgr.getAnalysisDeclContext(D);
549 const Expr *CallE =
Call.getOriginExpr();
552 AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(D);
553 const StackFrameContext *CalleeSFC =
554 CalleeADC->
getStackFrame(ParentOfCallee, CallE, currBldrCtx->getBlock(),
555 currBldrCtx->blockCount(), currStmtIdx);
557 CallEnter Loc(CallE, CalleeSFC, CurLC);
561 State = State->enterStackFrame(
Call, CalleeSFC);
564 if (ExplodedNode *N = G.getNode(Loc, State,
false, &isNew)) {
565 N->addPredecessor(Pred, G);
575 Engine.FunctionSummaries->bumpNumTimesInlined(D);
584 if (!isSecondPhaseCTU())
587 VisitedCallees->insert(D);
596 assert(ReplayState == CallE &&
"Backtracked to the wrong call.");
618 evalCall(dstCallEvaluated, N, *CallTemplate);
631 const Expr *E =
Call.getOriginExpr();
638 for (
unsigned CallI = 0, CallN =
Call.getNumArgs(); CallI != CallN; ++CallI) {
639 unsigned I =
Call.getASTArgumentIndex(CallI);
644 ->getStackFrame()->getParent()
646 State = finishObjectConstruction(State, {E, I}, LC);
658 if (CleanedState == State) {
663 const Expr *E =
Call.getOriginExpr();
664 const LocationContext *LC =
Call.getLocationContext();
665 NodeBuilder B(Pred, Dst, *currBldrCtx);
666 static SimpleProgramPointTag
Tag(
"ExprEngine",
667 "Finish argument construction");
668 PreStmt PP(E, LC, &Tag);
669 B.generateNode(PP, CleanedState, Pred);
697 finishArgumentConstruction(dstArgumentCleanup, I,
Call);
725 if (
const MemRegion *MR =
Call.getArgSVal(Arg).getAsRegion())
733 if (State == I->getState())
743 const Expr *E =
Call.getOriginExpr();
750 switch (Msg->getMethodFamily()) {
757 return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
761 SVal ThisV =
C->getCXXThisVal();
762 ThisV = State->getSVal(ThisV.
castAs<
Loc>());
763 return State->BindExpr(E, LCtx, ThisV);
768 unsigned Count = currBldrCtx->blockCount();
772 assert(RTC->getStmt() ==
Call.getOriginExpr());
775 Call.getOriginExpr(), State, currBldrCtx, LCtx,
776 RTC->getConstructionContext(), CallOpts);
787 State = State->invalidateRegions(TargetR, Elem, Count, LCtx,
797 const auto *CNE = dyn_cast<CXXNewExpr>(E);
798 if (CNE && CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
799 R = svalBuilder.getConjuredHeapSymbolVal(Elem, LCtx, E->
getType(), Count);
804 if (
const Expr *SizeExpr = CNE->getArraySize().value_or(
nullptr)) {
805 ElementCount = State->getSVal(SizeExpr, LCtx);
807 ElementCount = svalBuilder.makeIntVal(1,
true);
813 svalBuilder.evalBinOp(State, BO_Mul, ElementCount, ElementSize,
814 svalBuilder.getArrayIndexType());
823 R = svalBuilder.conjureSymbolVal(Elem, LCtx, ResultTy, Count);
826 return State->BindExpr(E, LCtx, R);
841ExprEngine::CallInlinePolicy
847 switch (
Call.getKind()) {
855 return CIP_DisallowedAlways;
859 return CIP_DisallowedAlways;
869 if (llvm::isa_and_nonnull<NewAllocatedObjectConstructionContext>(CC) &&
870 !Opts.MayInlineCXXAllocator)
871 return CIP_DisallowedOnce;
874 if (!shouldInlineArrayConstruction(Pred->
getState(), CtorExpr, CurLC))
875 return CIP_DisallowedOnce;
890 return CIP_DisallowedAlways;
896 !Opts.ShouldIncludeTemporaryDtorsInCFG)
897 return CIP_DisallowedOnce;
903 return CIP_DisallowedOnce;
908 return CIP_DisallowedOnce;
920 return CIP_DisallowedAlways;
930 return CIP_DisallowedOnce;
936 !Opts.MayInlineCXXTemporaryDtors)
937 return CIP_DisallowedOnce;
943 return CIP_DisallowedOnce;
949 if (Opts.MayInlineCXXAllocator)
953 return CIP_DisallowedAlways;
955 if (!Opts.MayInlineObjCMethod)
956 return CIP_DisallowedAlways;
959 return CIP_DisallowedAlways;
1004 if (II->isStr(
"shared_ptr"))
1015bool ExprEngine::mayInlineDecl(AnalysisDeclContext *CalleeADC)
const {
1016 AnalyzerOptions &Opts = AMgr.getAnalyzerOptions();
1024 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeADC->
getDecl())) {
1026 if (!Opts.MayInlineTemplateFunctions)
1031 if (!Opts.MayInlineCXXStandardLibrary)
1038 if (!Opts.MayInlineCXXContainerMethods)
1039 if (!AMgr.isInCodeFile(FD->getLocation()))
1047 if (!Opts.MayInlineCXXSharedPtrDtor)
1055 const CFG *CalleeCFG = CalleeADC->
getCFG();
1060 if (isHuge(CalleeADC))
1065 if (!CalleeADC->
getAnalysis<RelaxedLiveVariables>())
1071bool ExprEngine::shouldInlineCall(
const CallEvent &
Call,
const Decl *D,
1078 AnalyzerOptions &Opts = AMgr.options;
1079 AnalysisDeclContextManager &ADCMgr = AMgr.getAnalysisDeclContextManager();
1080 AnalysisDeclContext *CalleeADC = ADCMgr.
getContext(D);
1088 if (!AMgr.shouldInlineCall())
1092 std::optional<bool> MayInline = Engine.FunctionSummaries->mayInline(D);
1100 if (mayInlineDecl(CalleeADC)) {
1101 Engine.FunctionSummaries->markMayInline(D);
1103 Engine.FunctionSummaries->markShouldNotInline(D);
1112 CallInlinePolicy CIP = mayInlineCallKind(
Call, Pred, Opts, CallOpts);
1113 if (CIP != CIP_Allowed) {
1114 if (CIP == CIP_DisallowedAlways) {
1115 assert(!MayInline || *MayInline);
1116 Engine.FunctionSummaries->markShouldNotInline(D);
1122 bool IsRecursive =
false;
1123 unsigned StackDepth = 0;
1126 (!isSmall(CalleeADC) || IsRecursive))
1130 if ((Engine.FunctionSummaries->getNumTimesInlined(D) >
1131 Opts.MaxTimesInlineLarge) &&
1132 isLarge(CalleeADC)) {
1133 NumReachedInlineCountMax++;
1137 if (HowToInline ==
Inline_Minimal && (!isSmall(CalleeADC) || IsRecursive))
1143bool ExprEngine::shouldInlineArrayConstruction(
const ProgramStateRef State,
1144 const CXXConstructExpr *CE,
1145 const LocationContext *LCtx) {
1150 if (
const auto *CAT = dyn_cast<ConstantArrayType>(CE->
getType())) {
1161 return shouldInlineArrayDestruction(ArrSize);
1166 return shouldInlineArrayDestruction(*Size);
1171bool ExprEngine::shouldInlineArrayDestruction(uint64_t Size) {
1173 uint64_t maxAllowedSize = AMgr.options.maxBlockVisitOnPath;
1176 return Size <= maxAllowedSize && Size > 0;
1180 const CXXConstructExpr *E,
1181 const LocationContext *LCtx) {
1189 if (
const auto *CAT = dyn_cast<ConstantArrayType>(Ty)) {
1223 performTrivialCopy(Bldr, Pred, *
Call);
1230 const Expr *E =
Call->getOriginExpr();
1233 if (InlinedFailedState) {
1235 State = InlinedFailedState;
1240 if (shouldInlineCall(*
Call, D, Pred, CallOpts)) {
1252 conservativeEvalCall(*
Call, Bldr, Pred, State);
1256 ctuBifurcate(*
Call, D, Bldr, Pred, State);
1263 State = removeStateTraitsUsedForArrayEvaluation(
1264 State, dyn_cast_or_null<CXXConstructExpr>(E),
Call->getLocationContext());
1267 conservativeEvalCall(*
Call, Bldr, Pred, State);
1270void ExprEngine::BifurcateCall(
const MemRegion *BifurReg,
1279 const unsigned *BState =
1280 State->get<DynamicDispatchBifurcationMap>(BifurReg);
1283 if (*BState == DynamicDispatchModeInlined)
1284 ctuBifurcate(
Call, D, Bldr, Pred, State);
1288 conservativeEvalCall(
Call, Bldr, Pred, State);
1295 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1296 DynamicDispatchModeInlined);
1297 ctuBifurcate(
Call, D, Bldr, Pred, IState);
1300 State->set<DynamicDispatchBifurcationMap>(BifurReg,
1301 DynamicDispatchModeConservative);
1302 conservativeEvalCall(
Call, Bldr, Pred, NoIState);
1304 NumOfDynamicDispatchPathSplits++;
1316 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)
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 obj-c messages.
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 obj-c messages.
WorkList * getCTUWorkList() const
WorkList * getWorkList() const
ImplTy::iterator iterator
void insert(const ExplodedNodeSet &S)
void Add(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 ...
const StackFrameContext * getStackFrame() const
const LocationContext * getLocationContext() const
std::optional< T > getLocationAs() const &
ExplodedNode * getFirstPred()
ProgramStateManager & getStateManager()
void processCallEnter(NodeBuilderContext &BC, CallEnter CE, ExplodedNode *Pred)
Generate the entry node of the callee.
void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, const BlockEdge &L)
Called by CoreEngine.
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 VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitReturnStmt - Transfer function logic for return statements.
const CoreEngine & getCoreEngine() const
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.
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.
CheckerManager & getCheckerManager() const
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.
void removeDeadOnEndOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Remove dead bindings/symbols before exiting a function.
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
AnalysisManager & getAnalysisManager()
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
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path.
This is the simplest builder which generates nodes in the ExplodedGraph.
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
void takeNodes(const ExplodedNodeSet &S)
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.
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
This builder class is useful for generating nodes that resulted from visiting a statement.
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
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.