25#include "llvm/ADT/STLExtras.h"
26#include "llvm/ADT/Sequence.h"
27#include "llvm/Support/Casting.h"
41 state = createTemporaryRegionIfNeeded(state, SF, tempExpr, ME);
50 bool AlwaysReturnsLValue;
53 assert(Ctor->getDecl()->isTrivial());
54 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
55 ThisVal = Ctor->getCXXThisVal();
57 AlwaysReturnsLValue =
false;
64 AlwaysReturnsLValue =
true;
77 const Expr *VExpr =
Call.getArgExpr(0);
81 if (std::optional<Loc> L =
V.getAs<
Loc>())
84 assert(
V.isUnknownOrUndef());
90 evalBind(Dst,
CallExpr, N, ThisVal,
V, !AlwaysReturnsLValue);
99 PostStmt PS(CallExpr, SF);
100 for (ExplodedNode *N : Dst) {
102 if (AlwaysReturnsLValue)
103 State = State->BindExpr(CallExpr, SF, ThisVal);
111 QualType &Ty,
bool &IsArray,
unsigned Idx) {
112 SValBuilder &SVB = State->getStateManager().getSValBuilder();
117 Ty = AT->getElementType();
118 AT = dyn_cast<ArrayType>(AT->getElementType());
145 const auto *DS = DSCC->getDeclStmt();
148 return makeElementRegion(State, State->getLValue(Var, SF), Ty,
154 const auto *
Init = ICC->getCXXCtorInitializer();
157 SVal ThisVal = State->getSVal(ThisPtr);
158 if (
Init->isBaseInitializer()) {
161 Init->getBaseClass()->getAsCXXRecordDecl();
162 const auto *BaseReg =
163 MRMgr.getCXXBaseObjectRegion(BaseClass, ThisReg,
164 Init->isBaseVirtual());
167 if (
Init->isDelegatingInitializer())
172 if (
Init->isIndirectMemberInitializer()) {
173 Field =
Init->getIndirectMember();
174 FieldVal = State->getLValue(
Init->getIndirectMember(), ThisVal);
176 Field =
Init->getMember();
177 FieldVal = State->getLValue(
Init->getMember(), ThisVal);
185 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
187 const auto *NE = NECC->getCXXNewExpr();
190 dyn_cast_or_null<SubRegion>(
V.getAsRegion())) {
194 auto Ty = NE->getType()->getPointeeType();
195 while (
const auto *AT =
getContext().getAsArrayType(Ty))
196 Ty = AT->getElementType();
198 auto R = MRMgr.getElementRegion(Ty, svalBuilder.makeArrayIndex(Idx),
228 RTC->getConstructionContext(), CallOpts);
242 static const int TopLevelSymRegionTag = 0;
243 const Expr *RetE = RCC->getReturnStmt()->getRetValue();
244 assert(RetE &&
"Void returns should not have a construction context");
250 llvm_unreachable(
"Unhandled return value construction context!");
253 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
267 TCC->getConstructorAfterElision(), State, NumVisitedCaller, SF,
268 TCC->getConstructionContextAfterElision(), CallOpts);
278 CallOpts = PreElideCallOpts;
291 if (!VD->getType()->isReferenceType()) {
302 MRMgr.getCXXStaticLifetimeExtendedObjectRegion(E, VD));
305 MRMgr.getCXXLifetimeExtendedObjectRegion(E, VD, SF));
318 MRMgr.getCXXTempObjectRegion(LCC->getInitializer(), SF));
320 const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E);
323 Base = State->getLValue(E->
getType(), svalBuilder.makeArrayIndex(Idx),
334 const Expr *E = ACC->getCallLikeExpr();
335 unsigned Idx = ACC->getIndex();
338 auto getArgLoc = [&](
CallEventRef<> Caller) -> std::optional<SVal> {
340 Caller->getCalleeStackFrame(NumVisitedCaller);
359 *Caller->getAdjustedParameterIndex(Idx), NumVisitedCaller);
366 if (
const auto *CE = dyn_cast<CallExpr>(E)) {
369 if (std::optional<SVal>
V = getArgLoc(Caller))
373 }
else if (
const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
378 if (std::optional<SVal>
V = getArgLoc(Caller))
382 }
else if (
const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
385 if (std::optional<SVal>
V = getArgLoc(Caller))
411 assert(CC &&
"Computed target region without construction context?");
416 return addObjectUnderConstruction(State, DSCC->getDeclStmt(), SF,
V);
421 const auto *
Init = ICC->getCXXCtorInitializer();
423 assert(
Init->isAnyMemberInitializer() &&
424 "Base and delegating initializers should have been handled by"
425 "computeObjectUnderConstruction()");
426 return addObjectUnderConstruction(State,
Init, SF,
V);
441 assert(RTC &&
"Could not have had a target region without it");
444 V, SF->
getCallSite(), State, CallerSF, RTC->getConstructionContext(),
448 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors);
452 V, TCC->getConstructorAfterElision(), State, SF,
453 TCC->getConstructionContextAfterElision(), CallOpts);
456 State = addObjectUnderConstruction(
457 State, TCC->getConstructorAfterElision(), SF,
V);
460 if (
const auto *BTE = TCC->getCXXBindTemporaryExpr())
461 State = elideDestructor(State, BTE, SF);
465 if (
const auto *MTE = TCC->getMaterializedTemporaryExpr())
466 State = addObjectUnderConstruction(State, MTE, SF,
V);
476 if (
const auto *BTE = TCC->getCXXBindTemporaryExpr())
477 State = addObjectUnderConstruction(State, BTE, SF,
V);
479 if (
const auto *MTE = TCC->getMaterializedTemporaryExpr())
480 State = addObjectUnderConstruction(State, MTE, SF,
V);
489 if (
const auto *EL = dyn_cast_or_null<ElementRegion>(
V.getAsRegion()))
492 return addObjectUnderConstruction(
493 State, {LCC->getLambdaExpr(), LCC->getIndex()}, SF,
V);
497 if (
const auto *BTE = ACC->getCXXBindTemporaryExpr())
498 State = addObjectUnderConstruction(State, BTE, SF,
V);
500 return addObjectUnderConstruction(
501 State, {ACC->getCallLikeExpr(), ACC->getIndex()}, SF,
V);
504 llvm_unreachable(
"Unhandled construction context!");
522 const auto *SourceArrayRegion =
530void ExprEngine::handleConstructor(
const Expr *E,
533 const auto *CE = dyn_cast<CXXConstructExpr>(E);
534 const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(E);
540 SVal
Target = UnknownVal();
543 if (std::optional<SVal> ElidedTarget =
549 NodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
550 State = finishObjectConstruction(State, CE, SF);
551 if (
auto L =
Target.getAs<Loc>())
552 State = State->BindExpr(CE, SF, State->getSVal(*L, CE->getType()));
558 EvalCallOptions CallOpts;
561 const ConstructionContext *CC =
C ?
C->getConstructionContext() :
nullptr;
564 CE ? CE->getConstructionKind() : CIE->getConstructionKind();
568 assert(CE && !CIE &&
"A complete constructor is inherited?!");
575 if (CE->getType()->isArrayType() || AILE) {
577 auto isZeroSizeArray = [&] {
580 if (
const auto *CAT = dyn_cast<ConstantArrayType>(CE->getType()))
589 if (isZeroSizeArray()) {
590 NodeBuilder Bldr(Pred, destNodes, *currBldrCtx);
591 static SimpleProgramPointTag T{
"ExprEngine",
592 "Skipping 0 size array construction"};
598 State = setIndexOfElementToConstruct(State, CE, SF, Idx + 1);
604 State = setPendingInitLoop(
605 State, CE, SF,
getContext().getArrayInitLoopExprElementCount(AILE));
608 State, AILE, SF, svalBuilder.makeArrayIndex(Idx));
613 SF, CC, CallOpts, Idx);
619 const auto *OuterCtor =
620 dyn_cast_or_null<CXXConstructExpr>(SF->
getCallSite());
625 (
"This virtual base should have already been initialized by "
626 "the most derived class!"));
642 if (isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
645 Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, SF));
653 SVal ThisVal = State->getSVal(ThisPtr);
669 static SimpleProgramPointTag T(
"ExprEngine",
670 "Prepare for object construction");
671 ExplodedNodeSet DstPrepare;
672 NodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx);
679 const MemRegion *TargetRegion =
Target.getAsRegion();
681 CallEventRef<>
Call =
687 ExplodedNodeSet DstPreVisit;
690 ExplodedNodeSet PreInitialized;
693 NodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
694 for (ExplodedNode *N : DstPreVisit) {
696 if (CE->requiresZeroInitialization()) {
709 const CXXRecordDecl *TargetHeldRecord =
710 dyn_cast_or_null<CXXRecordDecl>(CE->getType()->getAsRecordDecl());
712 if (!TargetHeldRecord || !TargetHeldRecord->
isEmpty())
713 State = State->bindDefaultZero(
Target, SF);
720 PreInitialized = DstPreVisit;
723 ExplodedNodeSet DstPreCall;
727 ExplodedNodeSet DstEvaluated;
729 if (CE && CE->getConstructor()->isTrivial() &&
730 CE->getConstructor()->isCopyOrMoveConstructor() &&
732 NodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
734 for (ExplodedNode *N : DstPreCall)
735 performTrivialCopy(Bldr, N, *
Call);
738 for (ExplodedNode *N : DstPreCall)
750 ExplodedNodeSet DstEvaluatedPostProcessed;
751 NodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx);
754 if (llvm::isa_and_nonnull<CXXTempObjectRegion,
755 CXXLifetimeExtendedObjectRegion>(TargetRegion) &&
758 ->isAnyDestructorNoReturn()) {
767 assert(!DstEvaluated.
empty() &&
768 "We should not have inlined this constructor!");
770 for (ExplodedNode *N : DstEvaluated) {
781 ExplodedNodeSet DstPostArgumentCleanup;
782 for (ExplodedNode *I : DstEvaluatedPostProcessed)
783 finishArgumentConstruction(DstPostArgumentCleanup, I, *
Call);
787 ExplodedNodeSet DstPostCall;
789 DstPostArgumentCleanup,
797 handleConstructor(CE, Pred, Dst);
803 handleConstructor(CE, Pred, Dst);
813 assert(S &&
"A destructor without a trigger!");
818 assert(
RecordDecl &&
"Only CXXRecordDecls should have destructors");
841 if (
const Expr *E = dyn_cast_or_null<Expr>(S)) {
842 Dest = MRMgr.getCXXTempObjectRegion(E, Pred->
getStackFrame());
857 Call->getSourceRange().getBegin(),
858 "Error evaluating destructor");
865 NodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
880 "Error evaluating New Allocator Call");
890 NodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
907 NodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx);
919 SVal RetVal = State->getSVal(CNE, SF);
924 State = State->bindDefaultInitial(RetVal,
UndefinedVal{}, SF);
936 if (!ProtoType->isNothrow())
941 addObjectUnderConstruction(State, CNE, SF, RetVal));
946 DstPostValue, *
Call, *
this);
964 bool IsStandardGlobalOpNewFunction =
970 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
972 State = finishObjectConstruction(State, CNE, SF);
979 if (IsStandardGlobalOpNewFunction)
983 symVal = svalBuilder.conjureSymbolVal(
991 if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
996 State =
Call->invalidateRegions(blockCount, State);
1008 if (!ProtoType->isNothrow())
1010 State = State->assume(*dSymVal,
true);
1019 if (
const auto *NewReg = cast_or_null<SubRegion>(symVal.
getAsRegion())) {
1025 isa_and_nonnull<InitListExpr, CXXParenListInitExpr>(
Init);
1030 MRMgr.getElementRegion(ObjTy, svalBuilder.makeArrayIndex(0), NewReg,
1031 svalBuilder.getContext());
1042 evalBind(evaluated, CNE, Pred,
Result,
V,
true);
1047 Pred = *evaluated.
begin();
1069 State = State->BindExpr(CNE, SF,
Result);
1080 evalBind(Dst, CNE, NewN,
Result, State->getSVal(
Init, SF),
1081 IsStandardGlobalOpNewFunction);
1097 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
1098 NodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
1107 DstPostCall = std::move(DstPreCall);
1124 state = state->bindLoc(state->getLValue(VD, SF),
V, SF);
1136 const MemRegion *R = svalBuilder.getRegionManager().getCXXThisRegion(
1150 svalBuilder.getRegionManager().getCXXTempObjectRegion(LE, SF);
1157 for (
auto const [Idx, FieldForCapture, InitExpr] :
1158 llvm::zip(llvm::seq<unsigned>(0, -1), LE->getLambdaClass()->fields(),
1159 LE->capture_inits())) {
1160 SVal FieldLoc = State->getLValue(FieldForCapture,
V);
1163 if (!FieldForCapture->hasCapturedVLAType()) {
1164 assert(InitExpr &&
"Capture missing initialization expression");
1170 const auto FTy = FieldForCapture->getType();
1171 if (FTy->isConstantArrayType() &&
1173 getContext().getAsConstantArrayType(FTy)) == 0)
1180 InitVal = State->getSVal(OUC->getAsRegion());
1182 State = finishObjectConstruction(State, {LE, Idx}, SF);
1184 InitVal = State->getSVal(InitExpr, SF);
1189 "VLA capture by value is a compile time error!");
1194 Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr();
1195 InitVal = State->getSVal(SizeExpr, SF);
1198 State = State->bindLoc(FieldLoc, InitVal, SF);
1204 SVal LambdaRVal = State->getSVal(R);
1209 Bldr.
generateNode(LE, Pred, State->BindExpr(LE, SF, LambdaRVal),
nullptr,
1222 NodeBuilder Bldr(CheckerPreStmt, EvalSet, *currBldrCtx);
1226 Visit(
Attr->getAssumption()->IgnoreParens(), N, EvalSet);
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static ProgramStateRef bindRequiredArrayElementToEnvironment(ProgramStateRef State, const ArrayInitLoopExpr *AILE, const StackFrame *SF, NonLoc Idx)
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
uint64_t getArrayInitLoopExprElementCount(const ArrayInitLoopExpr *AILE) const
Return number of elements initialized in an ArrayInitLoopExpr.
CFG::BuildOptions & getCFGBuildOptions()
Represents a loop initializing the elements of an array.
OpaqueValueExpr * getCommonExpr() const
Get the common subexpression shared by all initializations (the source array).
Attr - This represents one attribute.
Represents an attribute applied to a statement.
ArrayRef< const Attr * > getAttrs() const
Represents a function call that returns a C++ object by value.
std::optional< T > getAs() const
Convert to the specified CFGElement type, returning std::nullopt if this CFGElement is not of the des...
CXXCatchStmt - This represents a C++ catch block.
VarDecl * getExceptionDecl() const
Represents a call to a C++ constructor.
Represents a delete expression for memory deallocation and destructor calls, e.g.
Represents a C++ destructor within a class.
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a static or instance method of a struct/union/class.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Expr * getPlacementArg(unsigned I)
SourceLocation getBeginLoc() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
Represents a C++ struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
Represents the this expression in C++.
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++.
virtual const ArrayInitLoopExpr * getArrayInitLoop() const
@ CXX17ElidedCopyVariableKind
@ ElidedTemporaryObjectKind
@ SimpleTemporaryObjectKind
@ CXX17ElidedCopyConstructorInitializerKind
@ SimpleConstructorInitializerKind
@ SimpleReturnedValueKind
@ CXX17ElidedCopyReturnedValueKind
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Represents a function declaration or definition.
bool isReplaceableGlobalAllocationFunction(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
Represents a prototype with parameter type info, e.g.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Stmt * getParent(Stmt *) const
Represents a program point just after an implicit call event.
If a crash happens while one of these objects are live, the message is printed out along with the spe...
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
A (possibly-)qualified type.
Represents a struct/union/class.
It represents a stack frame of the call stack.
const ParentMap & getParentMap() const
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.
SourceLocation getEndLoc() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
const T * getAs() const
Member-template getAs<specific type>'.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
Represents a call to a C++ constructor.
Manages the lifetime of CallEvent objects.
CallEventRef< CXXConstructorCall > getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, ProgramStateRef State, const StackFrame *SF, CFGBlock::ConstCFGElementRef ElemRef)
CallEventRef< CXXAllocatorCall > getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, const StackFrame *SF, CFGBlock::ConstCFGElementRef ElemRef)
CallEventRef< CXXInheritedConstructorCall > getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E, const MemRegion *Target, ProgramStateRef State, const StackFrame *SF, CFGBlock::ConstCFGElementRef ElemRef)
CallEventRef< CXXDeallocatorCall > getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State, const StackFrame *SF, CFGBlock::ConstCFGElementRef ElemRef)
CallEventRef< CXXDestructorCall > getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, const MemRegion *Target, bool IsBase, ProgramStateRef State, const StackFrame *SF, CFGBlock::ConstCFGElementRef ElemRef)
CallEventRef< ObjCMethodCall > getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State, const StackFrame *SF, CFGBlock::ConstCFGElementRef ElemRef)
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.
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 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.
ElementRegion is used to represent both array elements and casts.
ExplodedNodeSet is a set of ExplodedNode * elements with the invariant that its elements cannot be nu...
void insert(ExplodedNode *N)
const ProgramStateRef & getState() const
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
const StackFrame * getStackFrame() const
ProgramStateManager & getStateManager()
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
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.
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.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
StoreManager & getStoreManager()
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
ProgramStateRef updateObjectsUnderConstruction(SVal V, const Expr *E, ProgramStateRef State, const StackFrame *SF, const ConstructionContext *CC, const EvalCallOptions &CallOpts)
Update the program state with all the path-sensitive information that's necessary to perform construc...
ConstCFGElementRef getCFGElementRef() const
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,...
SVal computeObjectUnderConstruction(const Expr *E, ProgramStateRef State, unsigned NumVisitedCaller, const StackFrame *SF, const ConstructionContext *CC, EvalCallOptions &CallOpts, unsigned Idx=0)
Find location of the object that is being constructed by a given constructor.
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
unsigned getNumVisitedCurrent() const
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
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.
SValBuilder & getSValBuilder()
void VisitAttributedStmt(const AttributedStmt *A, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitAttributedStmt - Transfer function logic for AttributedStmt.
unsigned getNumVisited(const StackFrame *SF, const CFGBlock *Block) const
const ElementRegion * getElementRegion(QualType elementType, NonLoc Idx, const SubRegion *superRegion, const ASTContext &Ctx)
getElementRegion - Retrieve the memory region associated with the associated element type,...
MemRegion - The root abstract class for all memory regions.
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.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
void addNodes(const ExplodedNodeSet &S)
const ExplodedNodeSet & getResults() const
SValBuilder & getSValBuilder()
CallEventManager & getCallEventManager()
MemRegionManager & getRegionManager()
ProgramStateManager & getStateManager()
NonLoc makeArrayIndex(uint64_t idx)
ASTContext & getContext()
loc::MemRegionVal makeLoc(SymbolRef sym)
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrame *SF)
Return a memory region for the 'this' object reference.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, ConstCFGElementRef elem, const StackFrame *SF, unsigned count)
Create a new symbol with a unique 'name'.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
const MemRegion * getAsRegion() const
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.
SubRegion - A region that subsets another larger region.
TypedValueRegion - An abstract class representing regions having a typed value.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ Result
The result type of a method or function.
auto getSpecificAttrs(const Container &container)
U cast(CodeGen::Address addr)
Expr * extractElementInitializerFromNestedAILE(const ArrayInitLoopExpr *AILE)
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 IsElidableCtorThatHasNotBeenElided
This call is a pre-C++17 elidable constructor that we failed to elide because we failed to compute th...
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...