23 using namespace clang;
34 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
43 bool AlwaysReturnsLValue;
46 assert(Ctor->getDecl()->isTrivial());
47 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
48 ThisVal = Ctor->getCXXThisVal();
50 AlwaysReturnsLValue =
false;
53 assert(cast<CXXMethodDecl>(Call.
getDecl())->getOverloadedOperator() ==
55 ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal();
56 ThisRD = cast<CXXMethodDecl>(Call.
getDecl())->getParent();
57 AlwaysReturnsLValue =
true;
83 evalBind(Dst, CallExpr, Pred, ThisVal, V,
true);
89 if (AlwaysReturnsLValue)
90 State = State->BindExpr(CallExpr, LCtx, ThisVal);
100 SValBuilder &SVB = State->getStateManager().getSValBuilder();
104 Ty = AT->getElementType();
112 std::pair<ProgramStateRef, SVal> ExprEngine::prepareForObjectConstruction(
125 const auto *DSCC = cast<VariableConstructionContext>(CC);
126 const auto *DS = DSCC->getDeclStmt();
127 const auto *Var = cast<VarDecl>(DS->getSingleDecl());
128 SVal LValue = State->getLValue(Var, LCtx);
133 addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, LValue);
134 return std::make_pair(State, LValue);
138 const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
139 const auto *Init = ICC->getCXXCtorInitializer();
140 assert(Init->isAnyMemberInitializer());
144 SVal ThisVal = State->getSVal(ThisPtr);
148 if (Init->isIndirectMemberInitializer()) {
149 Field = Init->getIndirectMember();
150 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
152 Field = Init->getMember();
153 FieldVal = State->getLValue(Init->getMember(), ThisVal);
157 FieldVal = makeZeroElementRegion(State, FieldVal, Ty,
159 State = addObjectUnderConstruction(State, Init, LCtx, FieldVal);
160 return std::make_pair(State, FieldVal);
164 const auto *NECC = cast<NewAllocatedObjectConstructionContext>(CC);
165 const auto *
NE = NECC->getCXXNewExpr();
173 return std::make_pair(
175 MR, NE->getType()->getPointeeType())));
177 return std::make_pair(State, V);
199 if (isa<BlockInvocationContext>(CallerLCtx)) {
202 CallerLCtx = CallerLCtx->getParent();
203 assert(!isa<BlockInvocationContext>(CallerLCtx));
205 return prepareForObjectConstruction(
207 RTC->getConstructionContext(), CallOpts);
218 const auto *RCC = cast<ReturnedValueConstructionContext>(CC);
221 static const int TopLevelSymRegionTag = 0;
222 const Expr *RetE = RCC->getReturnStmt()->getRetValue();
223 assert(RetE &&
"Void returns should not have a construction context");
228 return std::make_pair(State, V);
230 llvm_unreachable(
"Unhandled return value construction context!");
234 const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC);
250 std::tie(State, V) = prepareForObjectConstruction(
251 CE, State, LCtx, TCC->getConstructionContextAfterElision(), CallOpts);
258 State = addObjectUnderConstruction(State, CE, LCtx, V);
262 State = elideDestructor(State, BTE, LCtx);
267 State = addObjectUnderConstruction(State, MTE, LCtx, V);
269 return std::make_pair(State, V);
273 State = PreElideState;
274 CallOpts = PreElideCallOpts;
279 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
287 if (!VD->getType()->isReferenceType()) {
306 State = addObjectUnderConstruction(State, BTE, LCtx, V);
309 State = addObjectUnderConstruction(State, MTE, LCtx, V);
312 return std::make_pair(State, V);
318 const auto *ACC = cast<ArgumentConstructionContext>(CC);
319 const Expr *E = ACC->getCallLikeExpr();
320 unsigned Idx = ACC->getIndex();
327 Caller->getCalleeStackFrame(currBldrCtx->
blockCount());
345 const VarRegion *VR = Caller->getParameterLocation(
346 *Caller->getAdjustedParameterIndex(Idx), currBldrCtx->
blockCount());
353 if (
const auto *CE = dyn_cast<CallExpr>(E)) {
355 if (
auto OptV = getArgLoc(Caller))
359 State = addObjectUnderConstruction(State, {CE, Idx}, LCtx,
V);
360 }
else if (
const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
365 if (
auto OptV = getArgLoc(Caller))
369 State = addObjectUnderConstruction(State, {CCE, Idx}, LCtx,
V);
370 }
else if (
const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
372 if (
auto OptV = getArgLoc(Caller))
376 State = addObjectUnderConstruction(State, {ME, Idx}, LCtx,
V);
382 State = addObjectUnderConstruction(State, BTE, LCtx, V);
384 return std::make_pair(State, V);
391 return std::make_pair(
408 Target = *ElidedTarget;
410 State = finishObjectConstruction(State, CE, LCtx);
412 State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->
getType()));
428 std::tie(State, Target) =
429 prepareForObjectConstruction(CE, State, LCtx, CC, CallOpts);
435 const auto *OuterCtor = dyn_cast_or_null<CXXConstructExpr>(
441 (
"This virtual base should have already been initialized by " 442 "the most derived class!"));
469 SVal ThisVal = State->getSVal(ThisPtr);
487 "Prepare for object construction");
491 assert(DstPrepare.
size() <= 1);
492 if (DstPrepare.
size() == 0)
494 Pred = *BldrPrepare.
begin();
509 E = DstPreVisit.
end();
525 State = State->bindDefaultZero(Target, LCtx);
546 performTrivialCopy(Bldr, *I, *Call);
563 const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
564 if (Target && isa<CXXTempObjectRegion>(Target) &&
565 Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
574 assert(!DstEvaluated.
empty() &&
575 "We should not have inlined this constructor!");
589 for (
auto I : DstEvaluated)
590 finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);
596 DstPostArgumentCleanup,
608 assert(S &&
"A destructor without a trigger!");
613 assert(RecordDecl &&
"Only CXXRecordDecls should have destructors");
624 Bldr.generateNode(PP, Pred->
getState(), Pred);
635 if (
const Expr *E = dyn_cast_or_null<Expr>(S)) {
651 Call->getSourceRange().getBegin(),
652 "Error evaluating destructor");
675 "Error evaluating New Allocator Call");
678 CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
686 for (
auto I : DstPreCall) {
696 for (
auto I : DstPostCall) {
707 SVal RetVal = State->getSVal(CNE, LCtx);
719 if (!ProtoType->isNothrow())
724 CNE, I, addObjectUnderConstruction(State, CNE, LCtx, RetVal));
729 DstPostValue, *Call, *
this);
730 for (
auto I : DstPostPostCallCallback) {
744 unsigned blockCount = currBldrCtx->
blockCount();
749 bool IsStandardGlobalOpNewFunction =
757 State = finishObjectConstruction(State, CNE, LCtx);
764 if (IsStandardGlobalOpNewFunction)
780 State = Call->invalidateRegions(blockCount);
794 if (!ProtoType->isNothrow())
796 State = State->assume(*dSymVal,
true);
802 SVal Result = symVal;
807 if (
const auto *NewReg = cast_or_null<SubRegion>(symVal.
getAsRegion())) {
830 State = State->BindExpr(CNE, LCtx, Result);
838 if (!isa<CXXConstructExpr>(Init)) {
841 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
842 IsStandardGlobalOpNewFunction);
867 state = state->bindLoc(state->getLValue(VD, LCtx),
V, LCtx);
886 Bldr.
generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
905 i != e; ++i, ++CurField) {
907 SVal FieldLoc = State->getLValue(FieldForCapture, V);
912 assert(InitExpr &&
"Capture missing initialization expression");
913 InitVal = State->getSVal(InitExpr, LocCtxt);
919 InitVal = State->getSVal(SizeExpr, LocCtxt);
922 State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
928 SVal LambdaRVal = State->getSVal(R);
934 State->BindExpr(LE, LocCtxt, LambdaRVal),
bool hasCapturedVLAType() const
Determine whether this member captures the variable length array type.
Represents a function declaration or definition.
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
SVal evalDerivedToBase(SVal Derived, const CastExpr *Cast)
Evaluates a chain of derived-to-base casts through the path specified in Cast.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
bool IsTemporaryCtorOrDtor
This call is a constructor or a destructor of a temporary value.
ImplTy::iterator iterator
unsigned blockCount() const
Returns the number of times the current basic block has been visited on the exploded graph path...
Stmt - This represents one statement.
This builder class is useful for generating nodes that resulted from visiting a statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Decl - This represents one declaration (or definition), e.g.
Defines the PrettyStackTraceEntry class, which is used to make crashes give more contextual informati...
FunctionDecl * getOperatorNew() const
Manages the lifetime of CallEvent objects.
ProgramPoint withTag(const ProgramPointTag *tag) const
Create a new ProgramPoint object that is the same as the original except for using the specified tag ...
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called...
CallEventRef< CXXDestructorCall > getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, const MemRegion *Target, bool IsBase, ProgramStateRef State, const LocationContext *LCtx)
Stmt * getParent(Stmt *) const
Hints for figuring out of a call should be inlined during evalCall().
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a call to a C++ constructor.
bool IsArrayCtorOrDtor
This call is a constructor or a destructor for a single element within an array, a part of array cons...
CallEventRef getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx)
const ProgramStateRef & getState() const
SVal evalCast(SVal val, QualType castTy, QualType originalType)
Represents a prvalue temporary that is written into memory so that a reference can bind to it...
const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
void takeNodes(const ExplodedNodeSet &S)
Represents a variable declaration or definition.
const T * getAs() const
Member-template getAs<specific type>'.
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
static 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, retrieve such object's location.
const ElementRegion * GetElementZeroRegion(const SubRegion *R, QualType T)
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
Represents a function call that returns a C++ object by value.
Represents a struct/union/class.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
MemRegionManager & getRegionManager()
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Represents a member of a struct/union/class.
AnalysisDeclContext contains the context data for the function or method under analysis.
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
bool isReplaceableGlobalAllocationFunction(bool *IsAligned=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
ExplodedNode * generateSink(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng)
Run checkers for pre-visiting obj-c messages.
CFGElement getCurrentCFGElement()
Return the CFG element corresponding to the worklist element that is currently being processed by Exp...
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Expr * getInitializer()
The initializer of this new-expression.
const LocationContext * getLocationContext() const
const LocationContext * getParent() const
If a crash happens while one of these objects are live, the message is printed out along with the spe...
Expr * getSizeExpr() const
field_iterator field_begin() const
Represents binding an expression to a temporary.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &Call, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting obj-c messages.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
static bool isVariadic(const Decl *D)
Returns true if the given decl is known to be variadic.
Represents the this expression in C++.
const CFGBlock * getCallSiteBlock() const
void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, SVal location, SVal Val, bool atDeclInit=false, const ProgramPoint *PP=nullptr)
evalBind - Handle the semantics of binding a value to a specific location.
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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Represents a prototype with parameter type info, e.g.
const Stmt * getCallSite() const
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void runCheckersForPostStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng, bool wasInlined=false)
Run checkers for post-visiting Stmts.
ExplodedNode * generateSink(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a sink in the ExplodedGraph.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Represents a C++ destructor within a class.
AnalyzerOptions & getAnalyzerOptions() override
VarDecl * getExceptionDecl() const
This is the simplest builder which generates nodes in the ExplodedGraph.
Represents C++ constructor call.
void Add(ExplodedNode *N)
const ExplodedNodeSet & getResults()
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called.
ASTContext & getContext() const
getContext - Return the ASTContext associated with this analysis.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
CallEventRef< ObjCMethodCall > getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State, const LocationContext *LCtx)
NonLoc makeZeroArrayIndex()
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
SourceLocation getEndLoc() const LLVM_READONLY
void runCheckersForNewAllocator(const CXXNewExpr *NE, SVal Target, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng, bool wasInlined=false)
Run checkers between C++ operator new and constructor calls.
CallEventRef< CXXAllocatorCall > getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State, const LocationContext *LCtx)
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
const MemRegion * getAsRegion() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
SourceLocation getBeginLoc() const
const VariableArrayType * getCapturedVLAType() const
Get the captured variable length array type.
CallEventManager & getCallEventManager()
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
Represents a static or instance method of a struct/union/class.
ASTContext & getContext()
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
bool IsCtorOrDtorWithImproperlyModeledTargetRegion
This call is a constructor or a destructor for which we do not currently compute the this-region corr...
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
void runCheckersForPreStmt(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const Stmt *S, ExprEngine &Eng)
Run checkers for pre-visiting Stmts.
DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E, const LocationContext *LCtx, unsigned Count)
Conjure a symbol representing heap allocated memory region.
const CXXThisRegion * getCXXThisRegion(QualType thisPointerTy, const LocationContext *LC)
getCXXThisRegion - Retrieve the [artificial] region associated with the parameter 'this'...
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
Dataflow Directional Tag Classes.
CFG::BuildOptions & getCFGBuildOptions()
Return the build options used to construct the CFG.
SValBuilder & getSValBuilder()
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
StoreManager & getStoreManager()
Represents a program point just after an implicit call event.
bool NE(InterpState &S, CodePtr OpPC)
void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitLambdaExpr - Transfer function logic for LambdaExprs.
Represents an abstract call to a function or method along a particular path.
Expr * getPlacementArg(unsigned I)
ProgramStateManager & getStateManager() override
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
const Decl * getDecl() const
const CXXTempObjectRegion * getCXXStaticTempObjectRegion(const Expr *Ex)
Create a CXXTempObjectRegion for temporaries which are lifetime-extended by static references...
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, EvalCallOptions &Options)
void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred, const CallEvent &Call, const EvalCallOptions &CallOpts={})
Default implementation of call evaluation.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SubRegion - A region that subsets another larger region.
void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst)
unsigned getIndex() const
const StackFrameContext * getStackFrame() const
CallEventRef< CXXConstructorCall > getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target, ProgramStateRef State, const LocationContext *LCtx)
ExplodedNode * generateNode(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred)
Generates a node in the ExplodedGraph.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
ConstructionContext's subclasses describe different ways of constructing an object in C++...
static bool isTrivial(ASTContext &Ctx, const Expr *E)
Checks if the expression is constant or does not have non-trivial function calls. ...
Represents a C++ struct/union/class.
bool IsTemporaryLifetimeExtendedViaAggregate
This call is a constructor for a temporary that is lifetime-extended by binding it to a reference-typ...
CXXCatchStmt - This represents a C++ catch block.
bool LE(InterpState &S, CodePtr OpPC)
const ParentMap & getParentMap() const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Full-expression storage duration (for temporaries).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
ExplodedNode * generateNode(const Stmt *S, ExplodedNode *Pred, ProgramStateRef St, const ProgramPointTag *tag=nullptr, ProgramPoint::Kind K=ProgramPoint::PostStmtKind)
iterator begin()
Iterators through the results frontier.
ElementRegion is used to represent both array elements and casts.
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression...
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
AnalysisDeclContext * getAnalysisDeclContext() const
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Create a C++ temporary object for an rvalue.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
Represents a call to a C++ constructor.
bool isUnknownOrUndef() const
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point...
ConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...