20 #include "llvm/ADT/SmallSet.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/Support/raw_ostream.h"
24 using namespace clang;
29 assert(E &&
"Calls without origin expressions do not have results");
71 for (
const auto *I : RD->
fields()) {
92 I != E && Idx < NumOfArgs; ++I, ++Idx) {
132 I != E; ++I, ++Idx) {
134 PreserveArgs.insert(Idx);
144 if (callee->hasAttr<PureAttr>() || callee->hasAttr<ConstAttr>())
153 llvm::SmallSet<unsigned, 4> PreserveArgs;
160 if (PreserveArgs.count(Idx))
166 ValuesToInvalidate.push_back(
getArgSVal(Idx));
172 return Result->invalidateRegions(ValuesToInvalidate,
getOriginExpr(),
175 nullptr,
this, &ETraits);
187 assert(D &&
"Cannot get a program point without a statement or decl");
206 return ArgE->getSourceRange();
233 Out <<
"Unknown call (type " <<
getKind() <<
")";
238 return isa<CallExpr>(
S) || isa<ObjCMessageExpr>(S)
239 || isa<CXXConstructExpr>(
S)
240 || isa<CXXNewExpr>(S);
246 return FD->getReturnType();
248 return MD->getReturnType();
249 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
261 Ty = FT->getReturnType();
269 llvm_unreachable(
"unknown callable kind");
276 return FD->isVariadic();
278 return MD->isVariadic();
279 if (
const BlockDecl *BD = dyn_cast<BlockDecl>(D))
280 return BD->isVariadic();
282 llvm_unreachable(
"unknown callable kind");
289 ArrayRef<ParmVarDecl*> parameters) {
296 ArrayRef<ParmVarDecl*>::iterator I = parameters.begin(), E = parameters.end();
297 for (; I != E && Idx < NumArgs; ++I, ++Idx) {
299 assert(ParamDecl &&
"Formal parameter has no decl?");
304 Bindings.push_back(std::make_pair(ParamLoc, ArgVal));
345 if (II->
isStr(
"pthread_setspecific"))
350 if (II->
isStr(
"xpc_connection_set_context"))
354 if (II->
isStr(
"funopen"))
357 StringRef FName = II->
getName();
361 if (FName.endswith(
"NoCopy"))
366 if (FName.startswith(
"NS") && (FName.find(
"Insert") != StringRef::npos))
371 if (FName.startswith(
"CF") || FName.startswith(
"CG")) {
372 return StrInStrNoCase(FName,
"InsertValue") != StringRef::npos ||
373 StrInStrNoCase(FName,
"AddValue") != StringRef::npos ||
374 StrInStrNoCase(FName,
"SetValue") != StringRef::npos ||
375 StrInStrNoCase(FName,
"WithData") != StringRef::npos ||
376 StrInStrNoCase(FName,
"AppendValue") != StringRef::npos ||
377 StrInStrNoCase(FName,
"SetAttribute") != StringRef::npos;
394 const CallExpr *CE = cast_or_null<CallExpr>(getOriginExpr());
402 return getSVal(CE->
getCallee()).getAsFunctionDecl();
406 Values.push_back(getCXXThisVal());
410 const Expr *
Base = getCXXThisExpr();
415 SVal ThisVal = getSVal(Base);
423 const Decl *D = getDecl();
433 const MemRegion *R = getCXXThisVal().getAsRegion();
444 assert(!RegionType.
isNull() &&
"DynamicTypeInfo should always be a pointer.");
447 if (!RD || !RD->hasDefinition())
457 assert(!RD->isDerivedFrom(MD->
getParent()) &&
"Couldn't find known method");
471 if (!Result->
hasBody(Definition))
484 BindingsTy &Bindings)
const {
488 SVal ThisVal = getCXXThisVal();
506 assert(!Failed &&
"Calling an incorrectly devirtualized method");
510 Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
517 return getOriginExpr()->getImplicitObjectArgument();
525 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(getOriginExpr()->getCallee()))
526 if (ME->hasQualifier())
534 return getOriginExpr()->getArg(0);
539 const Expr *Callee = getOriginExpr()->getCallee();
540 const MemRegion *DataReg = getSVal(Callee).getAsRegion();
542 return dyn_cast_or_null<BlockDataRegion>(DataReg);
554 if (
const MemRegion *R = getBlockRegion())
559 BindingsTy &Bindings)
const {
580 BindingsTy &Bindings)
const {
583 SVal ThisVal = getCXXThisVal();
588 Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
601 if (isBaseDestructor())
616 Values.push_back(getReceiverSVal());
624 return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx));
629 if (!isInstanceMessage())
632 if (
const Expr *RecE = getOriginExpr()->getInstanceReceiver())
633 return getSVal(RecE);
638 SVal SelfVal = getSelfSVal();
639 assert(SelfVal.
isValid() &&
"Calling super but not in ObjC method");
648 if (!isInstanceMessage())
651 SVal RecVal = getSVal(getOriginExpr()->getInstanceReceiver());
653 return (RecVal == getSelfSVal());
657 switch (getMessageKind()) {
659 return getOriginExpr()->getSourceRange();
662 return getContainingPseudoObjectExpr()->getSourceRange();
664 llvm_unreachable(
"unknown message kind");
669 const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr()
const {
670 assert(Data &&
"Lazy lookup not yet performed.");
671 assert(getMessageKind() !=
OCM_Message &&
"Explicit message send.");
672 return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
679 ParentMap &PM = getLocationContext()->getParentMap();
684 const Expr *Syntactic = POE->getSyntacticForm();
688 if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(Syntactic))
689 Syntactic = BO->getLHS();
692 switch (Syntactic->getStmtClass()) {
693 case Stmt::ObjCPropertyRefExprClass:
696 case Stmt::ObjCSubscriptRefExprClass:
708 assert(getMessageKind() == K);
720 if (!Info.getPointer())
730 getState()->getStateManager().getContext().getSourceManager();
778 llvm_unreachable(
"The while loop should always terminate.");
790 bool CanBeSubClassed =
false;
794 if (!SupersType.
isNull()) {
797 ReceiverT = cast<ObjCObjectPointerType>(SupersType);
799 Receiver = getReceiverSVal().getAsRegion();
808 if (ReceiverT && CanBeSubClassed)
810 if (!canBeOverridenInSubclass(IDecl, Sel))
811 CanBeSubClassed =
false;
831 typedef std::pair<const ObjCInterfaceDecl*, Selector>
833 typedef llvm::DenseMap<PrivateMethodKey,
837 static PrivateMethodCache PMC;
841 if (!Val.hasValue()) {
842 Val = IDecl->lookupPrivateMethod(Sel);
848 if (CompileTimeMD->isPropertyAccessor())
849 Val = IDecl->lookupInstanceMethod(Sel);
873 if (isInSystemHeader() && !isInstanceMessage()) {
885 BindingsTy &Bindings)
const {
891 SVal SelfVal = getReceiverSVal();
892 if (!SelfVal.isUnknown()) {
896 Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
904 return create<CXXMemberCall>(MCE,
State, LCtx);
907 const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
908 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DirectCallee))
909 if (MD->isInstance())
910 return create<CXXMemberOperatorCall>(OpCE, State, LCtx);
913 return create<BlockCall>(CE,
State, LCtx);
918 return create<SimpleFunctionCall>(CE,
State, LCtx);
927 assert(CallerCtx &&
"This should not be used for top-level stack frames");
932 if (
const CallExpr *CE = dyn_cast<CallExpr>(CallSite))
933 return getSimpleCall(CE, State, CallerCtx);
935 switch (CallSite->getStmtClass()) {
936 case Stmt::CXXConstructExprClass:
937 case Stmt::CXXTemporaryObjectExprClass: {
938 SValBuilder &SVB = State->getStateManager().getSValBuilder();
941 SVal ThisVal = State->getSVal(ThisPtr);
943 return getCXXConstructorCall(cast<CXXConstructExpr>(CallSite),
946 case Stmt::CXXNewExprClass:
947 return getCXXAllocatorCall(cast<CXXNewExpr>(CallSite), State, CallerCtx);
948 case Stmt::ObjCMessageExprClass:
949 return getObjCMethodCall(cast<ObjCMessageExpr>(CallSite),
952 llvm_unreachable(
"This is not an inlineable statement.");
961 "All other CFG elements should have exprs");
964 SValBuilder &SVB = State->getStateManager().getSValBuilder();
967 SVal ThisVal = State->getSVal(ThisPtr);
971 Trigger = AutoDtor->getTriggerStmt();
973 Trigger = cast<Stmt>(DeleteDtor->getDeleteExpr());
977 return getCXXDestructorCall(Dtor, Trigger, ThisVal.
getAsRegion(),
void getExtraInvalidatedValues(ValueList &Values) const override
llvm::PointerIntPair< const PseudoObjectExpr *, 2 > ObjCMessageDataTy
bool isObjCSelType() const
ArrayRef< ParmVarDecl * > parameters() const
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
A call to an overloaded operator written using operator syntax.
The receiver is the instance of the superclass object.
ArrayRef< ParmVarDecl * > parameters() const
Smart pointer class that efficiently represents Objective-C method names.
SVal evalDynamicCast(SVal Base, QualType DerivedPtrType, bool &Failed)
Evaluates C++ dynamic_cast cast. The callback may result in the following 3 scenarios: ...
MemRegion - The root abstract class for all memory regions.
bool canBeASubClass() const
Returns false if the type information is precise (the type T is the only type in the lattice)...
bool argumentsMayEscape() const override
Returns true if any of the arguments are known to escape to long- term storage, even if this method w...
void getExtraInvalidatedValues(ValueList &Values) const override
ObjCInterfaceDecl * getClassInterface()
IdentifierInfo * getIdentifier() const
Information about invalidation for a particular region/symbol.
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type...
virtual bool argumentsMayEscape() const
Returns true if any of the arguments are known to escape to long- term storage, even if this method w...
const ProgramStateRef & getState() const
The state in which the call is being evaluated.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
QualType getRecordType(const RecordDecl *Decl) const
SourceRange getSourceRange() const override
A container of type source information.
bool isBlockPointerType() const
CallEventRef getSimpleCall(const CallExpr *E, ProgramStateRef State, const LocationContext *LCtx)
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
const Expr * getCallee() const
loc::MemRegionVal getCXXThis(const CXXMethodDecl *D, const StackFrameContext *SFC)
Return a memory region for the 'this' object reference.
void setTrait(SymbolRef Sym, InvalidationKinds IK)
bool isReceiverSelfOrSuper() const
Checks if the receiver refers to 'self' or 'super'.
SVal getSelfSVal() const
Return the value of 'self' if available.
const Expr * getCXXThisExpr() const override
Returns the expression representing the implicit 'this' object.
ArrayRef< ParmVarDecl * > parameters() const override
param_type_iterator param_type_end() const
ParmVarDecl - Represents a parameter to a function.
bool isZeroConstant() const
const ImplicitParamDecl * getSelfDecl() const
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body (definition). The function body might be in any of the (re-)d...
RuntimeDefinition getRuntimeDefinition() const override
MemRegionManager & getRegionManager()
IdentifierInfo * getIdentifierInfoForSlot(unsigned argIndex) const
Retrieve the identifier at a given position in the selector.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isReferenceType() const
bool isOverriding() const
Whether this method overrides any other in the class hierarchy.
bool isAnyPointerType() const
AnalysisDeclContext * getAnalysisDeclContext() const
const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call. May be null.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
SValBuilder & getSValBuilder()
const FunctionDecl * getAsFunctionDecl() const
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Represents any expression that calls an Objective-C method.
virtual Kind getKind() const =0
Returns the kind of call this is.
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
unsigned getIndex() const
QualType getSuperType() const
Retrieve the type referred to by 'super'.
const CXXRecordDecl * getParent() const
An x-value expression is a reference to an object with independent storage but which can be "moved"...
const CFGBlock * getCallSiteBlock() const
field_range fields() const
static void findPtrToConstParams(llvm::SmallSet< unsigned, 4 > &PreserveArgs, const CallEvent &Call)
bool isUnknownOrUndef() const
void getExtraInvalidatedValues(ValueList &Values) const override
A builtin binary operation expression such as "x + y" or "x <= y".
Selector getSelector() const
const Stmt * getCallSite() const
static bool isPointerToConst(QualType Ty)
Returns true if a type is a pointer-to-const or reference-to-const with no further indirection...
const FunctionDecl * getDecl() const override
Returns the declaration of the function or method that will be called. May be null.
ProgramPoint getProgramPoint(bool IsPreVisit=false, const ProgramPointTag *Tag=nullptr) const
Returns an appropriate ProgramPoint for this call.
Represents an ObjC class declaration.
static bool isVariadic(const Decl *D)
Returns true if the given decl is known to be variadic.
CXXMethodDecl * getCorrespondingMethodInClass(const CXXRecordDecl *RD, bool MayBeBase=false)
Find the method in RD that corresponds to this one.
virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, Selector Sel) const
Check if the selector may have multiple definitions (may have overrides).
virtual SourceRange getArgSourceRange(unsigned Index) const
Returns the source range for errors associated with this argument.
const Expr * getCXXThisExpr() const override
Returns the expression representing the implicit 'this' object.
ObjCMessageKind
Represents the ways an Objective-C message send can occur.
bool isGlobalCFunction(StringRef SpecificName=StringRef()) const
Returns true if the callee is an externally-visible function in the top-level namespace, such as malloc.
bool isInstanceMessage() const
Determine whether this is an instance message to either a computed object or to super.
ArrayRef< ParmVarDecl * > parameters() const override
bool argumentsMayEscape() const override
const MemRegion * StripCasts(bool StripBaseCasts=true) const
QualType getPointeeType() const
Loc makeLoc(SymbolRef sym)
ArrayRef< ParmVarDecl * > parameters() const override
bool isFunctionPointerType() const
const ObjCMethodDecl * getMethodDecl() const
virtual const Expr * getArgExpr(unsigned Index) const
Returns the expression associated with a given argument. May be null if this expression does not appe...
StringRef getName() const
Return the actual identifier string.
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
Stores the currently inferred strictest bound on the runtime type of a region in a given state along ...
const FunctionDecl * getDecl() const override
Returns the declaration of the function or method that will be called. May be null.
unsigned getNumArgs() const
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name=StringRef())
Returns true if the callee is an externally-visible function in the top-level namespace, such as malloc.
Represents a C++ destructor within a class.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
param_type_iterator param_type_begin() const
bool isDependentType() const
RuntimeDefinition getRuntimeDefinition() const override
Returns the definition of the function or method that will be called.
QualType getType() const
Returns the currently inferred upper bound on the runtime type.
An expression that sends a message to the given Objective-C object or class.
StoreManager & getStoreManager()
The result type of a method or function.
const clang::PrintingPolicy & getPrintingPolicy() const
RuntimeDefinition getRuntimeDefinition() const override
static bool isCallbackArg(SVal V, QualType T)
ArrayRef< ParmVarDecl * > parameters() const
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
Stmt * getBody(const FunctionDecl *&Definition) const
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx, CallEvent::BindingsTy &Bindings, SValBuilder &SVB, const CallEvent &Call, ArrayRef< ParmVarDecl * > parameters)
Defines the runtime definition of the called function.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
const FunctionDecl * getDecl() const override
const BlockDataRegion * getBlockRegion() const
Returns the region associated with this instance of the block.
const StackFrameContext * getCurrentStackFrame() const
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
bool isValid() const
Return true if this is a valid SourceLocation object.
Represents a static or instance method of a struct/union/class.
ASTContext & getContext()
const Decl * getDecl() const
SourceLocation getBegin() const
virtual SourceRange getSourceRange() const
Returns a source range for the entire call, suitable for outputting in diagnostics.
RuntimeDefinition getRuntimeDefinition() const override
Tells that a region's contents is not changed.
virtual void getExtraInvalidatedValues(ValueList &Values) const
Used to specify non-argument regions that will be invalidated as a result of this call...
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called. May be null.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
ProgramStateRef invalidateRegions(unsigned BlockCount, ProgramStateRef Orig=nullptr) const
Returns a new state with all argument regions invalidated.
const LocationContext * getParent() const
void getExtraInvalidatedValues(ValueList &Values) const override
bool isValid() const
Return false if no dynamic type info is available.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
RuntimeDefinition getRuntimeDefinition() const override
const VarRegion * getVarRegion(const VarDecl *D, const LocationContext *LC)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
ProgramStateManager & getStateManager()
const MemRegion * getAsRegion() const
SourceLocation getEndOfDefinitionLoc() const
Represents an abstract call to a function or method along a particular path.
ObjCMessageKind getMessageKind() const
const RecordType * getAsStructureType() const
QualType getResultType() const
Returns the result type, adjusted for references.
ObjCMethodDecl * lookupMethod(Selector Sel, bool isInstance, bool shallowCategoryLookup=false, bool followSuper=true, const ObjCCategoryDecl *C=nullptr) const
ObjCInterfaceDecl * getInterfaceDecl() const
static QualType getDeclaredResultType(const Decl *D)
Returns the result type of a function or method declaration.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const ImplicitParamDecl * getSelfDecl() const
Represents a C++ struct/union/class.
SVal getCXXThisVal() const override
Returns the value of the implicit 'this' object.
Stmt * getParentIgnoreParenCasts(Stmt *) const
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
CFGElement - Represents a top-level expression in a basic block.
virtual const CallExpr * getOriginExpr() const
const LocationContext * getLocationContext() const
The context in which the call is being evaluated.
SVal getCXXThisVal() const
Returns the value of the implicit 'this' object.
ObjCInterfaceDecl * getSuperClass() const
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
virtual SVal getCXXThisVal() const
Returns the value of the implicit 'this' object.
llvm::mapped_iterator< ArrayRef< ParmVarDecl * >::iterator, get_type_fun > param_type_iterator
An l-value expression is a reference to an object with independent storage.
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
bool hasNonZeroCallbackArg() const
Returns true if any of the arguments appear to represent callbacks.
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
The receiver is a superclass.
SVal getReturnValue() const
Returns the return value of the call.
This class handles loading and caching of source files into memory.
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override
ArrayRef< SVal > ValueList