24 using namespace clang;
35 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME);
44 bool AlwaysReturnsLValue;
47 assert(Ctor->getDecl()->isTrivial());
48 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
49 ThisVal = Ctor->getCXXThisVal();
51 AlwaysReturnsLValue =
false;
54 assert(cast<CXXMethodDecl>(Call.
getDecl())->getOverloadedOperator() ==
56 ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal();
57 ThisRD = cast<CXXMethodDecl>(Call.
getDecl())->getParent();
58 AlwaysReturnsLValue =
true;
84 evalBind(Dst, CallExpr, Pred, ThisVal, V,
true);
90 if (AlwaysReturnsLValue)
91 State = State->BindExpr(CallExpr, LCtx, ThisVal);
101 SValBuilder &SVB = State->getStateManager().getSValBuilder();
105 Ty = AT->getElementType();
113 std::pair<ProgramStateRef, SVal> ExprEngine::prepareForObjectConstruction(
126 const auto *DSCC = cast<VariableConstructionContext>(CC);
127 const auto *DS = DSCC->getDeclStmt();
128 const auto *Var = cast<VarDecl>(DS->getSingleDecl());
129 SVal LValue = State->getLValue(Var, LCtx);
134 addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, LValue);
135 return std::make_pair(State, LValue);
139 const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC);
140 const auto *Init = ICC->getCXXCtorInitializer();
141 assert(Init->isAnyMemberInitializer());
145 SVal ThisVal = State->getSVal(ThisPtr);
149 if (Init->isIndirectMemberInitializer()) {
150 Field = Init->getIndirectMember();
151 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
153 Field = Init->getMember();
154 FieldVal = State->getLValue(Init->getMember(), ThisVal);
158 FieldVal = makeZeroElementRegion(State, FieldVal, Ty,
160 State = addObjectUnderConstruction(State, Init, LCtx, FieldVal);
161 return std::make_pair(State, FieldVal);
165 const auto *NECC = cast<NewAllocatedObjectConstructionContext>(CC);
166 const auto *NE = NECC->getCXXNewExpr();
174 return std::make_pair(
176 MR, NE->getType()->getPointeeType())));
178 return std::make_pair(State, V);
200 return prepareForObjectConstruction(
202 RTC->getConstructionContext(), CallOpts);
213 const auto *RCC = cast<ReturnedValueConstructionContext>(CC);
216 static const int TopLevelSymRegionTag = 0;
217 const Expr *RetE = RCC->getReturnStmt()->getRetValue();
218 assert(RetE &&
"Void returns should not have a construction context");
223 return std::make_pair(State, V);
225 llvm_unreachable(
"Unhandled return value construction context!");
229 const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC);
245 std::tie(State, V) = prepareForObjectConstruction(
246 CE, State, LCtx, TCC->getConstructionContextAfterElision(), CallOpts);
253 State = addObjectUnderConstruction(State, CE, LCtx, V);
257 State = elideDestructor(State, BTE, LCtx);
262 State = addObjectUnderConstruction(State, MTE, LCtx, V);
264 return std::make_pair(State, V);
268 State = PreElideState;
269 CallOpts = PreElideCallOpts;
274 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC);
282 if (!VD->getType()->isReferenceType()) {
301 State = addObjectUnderConstruction(State, BTE, LCtx, V);
304 State = addObjectUnderConstruction(State, MTE, LCtx, V);
307 return std::make_pair(State, V);
313 const auto *ACC = cast<ArgumentConstructionContext>(CC);
314 const Expr *E = ACC->getCallLikeExpr();
315 unsigned Idx = ACC->getIndex();
339 const VarRegion *VR = Caller->getParameterLocation(
340 *Caller->getAdjustedParameterIndex(Idx));
347 if (
const auto *CE = dyn_cast<CallExpr>(E)) {
349 if (
auto OptV = getArgLoc(Caller))
353 State = addObjectUnderConstruction(State, {CE, Idx}, LCtx, V);
354 }
else if (
const auto *CCE = dyn_cast<CXXConstructExpr>(E)) {
359 if (
auto OptV = getArgLoc(Caller))
363 State = addObjectUnderConstruction(State, {CCE, Idx}, LCtx, V);
364 }
else if (
const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
366 if (
auto OptV = getArgLoc(Caller))
370 State = addObjectUnderConstruction(State, {ME, Idx}, LCtx, V);
376 State = addObjectUnderConstruction(State, BTE, LCtx, V);
378 return std::make_pair(State, V);
385 return std::make_pair(
402 Target = *ElidedTarget;
404 State = finishObjectConstruction(State, CE, LCtx);
406 State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->
getType()));
422 std::tie(State, Target) =
423 prepareForObjectConstruction(CE, State, LCtx, CC, CallOpts);
468 SVal ThisVal = State->getSVal(ThisPtr);
486 "Prepare for object construction");
490 assert(DstPrepare.
size() <= 1);
491 if (DstPrepare.
size() == 0)
493 Pred = *BldrPrepare.
begin();
508 E = DstPreVisit.
end();
524 State = State->bindDefaultZero(Target, LCtx);
545 performTrivialCopy(Bldr, *I, *Call);
562 const MemRegion *Target = Call->getCXXThisVal().getAsRegion();
563 if (Target && isa<CXXTempObjectRegion>(Target) &&
564 Call->getDecl()->getParent()->isAnyDestructorNoReturn()) {
573 assert(!DstEvaluated.
empty() &&
574 "We should not have inlined this constructor!");
588 for (
auto I : DstEvaluated)
589 finishArgumentConstruction(DstPostArgumentCleanup, I, *Call);
595 DstPostArgumentCleanup,
611 assert(RecordDecl &&
"Only CXXRecordDecls should have destructors");
619 Call->getSourceRange().getBegin(),
620 "Error evaluating destructor");
644 "Error evaluating New Allocator Call");
647 CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
655 for (
auto I : DstPreCall) {
665 for (
auto I : DstPostCall) {
676 SVal RetVal = State->getSVal(CNE, LCtx);
688 if (!ProtoType->isNothrow())
693 CNE, I, addObjectUnderConstruction(State, CNE, LCtx, RetVal));
698 DstPostValue, *Call, *
this);
699 for (
auto I : DstPostPostCallCallback) {
713 unsigned blockCount = currBldrCtx->
blockCount();
718 bool IsStandardGlobalOpNewFunction =
726 State = finishObjectConstruction(State, CNE, LCtx);
733 if (IsStandardGlobalOpNewFunction)
748 State = Call->invalidateRegions(blockCount);
762 if (!ProtoType->isNothrow())
764 State = State->assume(*dSymVal,
true);
770 SVal Result = symVal;
776 dyn_cast_or_null<SubRegion>(symVal.
getAsRegion())) {
799 State = State->BindExpr(CNE, LCtx, Result);
807 if (!isa<CXXConstructExpr>(Init)) {
810 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx),
811 IsStandardGlobalOpNewFunction);
836 state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
855 Bldr.
generateNode(TE, Pred, state->BindExpr(TE, LCtx, V));
874 i != e; ++i, ++CurField) {
876 SVal FieldLoc = State->getLValue(FieldForCapture, V);
881 assert(InitExpr &&
"Capture missing initialization expression");
882 InitVal = State->getSVal(InitExpr, LocCtxt);
888 InitVal = State->getSVal(SizeExpr, LocCtxt);
891 State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
897 SVal LambdaRVal = State->getSVal(R);
903 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.
PointerType - C99 6.7.5.1 - Pointer Declarators.
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.
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.
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]).
Expr * GetTemporaryExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue...
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
const ValueDecl * getExtendingDecl() const
Get the declaration which triggered the lifetime-extension of this temporary, if any.
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
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.
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)
ParentMap & getParentMap() const
NonLoc makeZeroArrayIndex()
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
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...
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()
void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, const EvalCallOptions &Options)
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 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++...
Represents a C++ struct/union/class.
bool isTrivial(const SExpr *E)
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.
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.
Represents a call to a C++ constructor.
bool isUnknownOrUndef() const
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
ConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...