本文整理汇总了C++中ObjCMethodCall::getReceiverSVal方法的典型用法代码示例。如果您正苦于以下问题:C++ ObjCMethodCall::getReceiverSVal方法的具体用法?C++ ObjCMethodCall::getReceiverSVal怎么用?C++ ObjCMethodCall::getReceiverSVal使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ObjCMethodCall
的用法示例。
在下文中一共展示了ObjCMethodCall::getReceiverSVal方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: checkPreObjCMessage
/// If we are in -dealloc or -dealloc is on the stack, handle the call if it is
/// a release or a nilling-out property setter.
void ObjCDeallocChecker::checkPreObjCMessage(
const ObjCMethodCall &M, CheckerContext &C) const {
// Only run if -dealloc is on the stack.
SVal DeallocedInstance;
if (!instanceDeallocIsOnStack(C, DeallocedInstance))
return;
SymbolRef ReleasedValue = nullptr;
if (M.getSelector() == ReleaseSel) {
ReleasedValue = M.getReceiverSVal().getAsSymbol();
} else if (M.getSelector() == DeallocSel && !M.isReceiverSelfOrSuper()) {
if (diagnoseMistakenDealloc(M.getReceiverSVal().getAsSymbol(), M, C))
return;
}
if (ReleasedValue) {
// An instance variable symbol was released with -release:
// [_property release];
if (diagnoseExtraRelease(ReleasedValue,M, C))
return;
} else {
// An instance variable symbol was released nilling out its property:
// self.property = nil;
ReleasedValue = getValueReleasedByNillingOut(M, C);
}
if (!ReleasedValue)
return;
transitionToReleaseValue(C, ReleasedValue);
}
示例2: checkPostObjCMessage
void ObjCLoopChecker::checkPostObjCMessage(const ObjCMethodCall &M,
CheckerContext &C) const {
if (!M.isInstanceMessage())
return;
const ObjCInterfaceDecl *ClassID = M.getReceiverInterface();
if (!ClassID)
return;
FoundationClass Class = findKnownClass(ClassID);
if (Class != FC_NSDictionary &&
Class != FC_NSArray &&
Class != FC_NSSet)
return;
SymbolRef ContainerS = M.getReceiverSVal().getAsSymbol();
if (!ContainerS)
return;
// If we are processing a call to "count", get the symbolic value returned by
// a call to "count" and add it to the map.
if (!isCollectionCountMethod(M, C))
return;
const Expr *MsgExpr = M.getOriginExpr();
SymbolRef CountS = C.getSVal(MsgExpr).getAsSymbol();
if (CountS) {
ProgramStateRef State = C.getState();
C.getSymbolManager().addSymbolDependency(ContainerS, CountS);
State = State->set<ContainerCountMap>(ContainerS, CountS);
C.addTransition(State);
}
return;
}
示例3: getReceiverNullability
static Nullability getReceiverNullability(const ObjCMethodCall &M,
ProgramStateRef State) {
if (M.isReceiverSelfOrSuper()) {
// For super and super class receivers we assume that the receiver is
// nonnull.
return Nullability::Nonnull;
}
// Otherwise look up nullability in the state.
SVal Receiver = M.getReceiverSVal();
if (auto DefOrUnknown = Receiver.getAs<DefinedOrUnknownSVal>()) {
// If the receiver is constrained to be nonnull, assume that it is nonnull
// regardless of its type.
NullConstraint Nullness = getNullConstraint(*DefOrUnknown, State);
if (Nullness == NullConstraint::IsNotNull)
return Nullability::Nonnull;
}
auto ValueRegionSVal = Receiver.getAs<loc::MemRegionVal>();
if (ValueRegionSVal) {
const MemRegion *SelfRegion = ValueRegionSVal->getRegion();
assert(SelfRegion);
const NullabilityState *TrackedSelfNullability =
State->get<NullabilityMap>(SelfRegion);
if (TrackedSelfNullability)
return TrackedSelfNullability->getValue();
}
return Nullability::Unspecified;
}
示例4: checkPreObjCMessage
void ObjCSuperDeallocChecker::checkPreObjCMessage(const ObjCMethodCall &M,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
SymbolRef ReceiverSymbol = M.getReceiverSVal().getAsSymbol();
if (!ReceiverSymbol) {
diagnoseCallArguments(M, C);
return;
}
bool AlreadyCalled = State->contains<CalledSuperDealloc>(ReceiverSymbol);
if (!AlreadyCalled)
return;
StringRef Desc;
if (isSuperDeallocMessage(M)) {
Desc = "[super dealloc] should not be called multiple times";
} else {
Desc = StringRef();
}
reportUseAfterDealloc(ReceiverSymbol, Desc, M.getOriginExpr(), C);
return;
}
示例5: checkPreObjCMessage
void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
SVal recVal = msg.getReceiverSVal();
if (recVal.isUndef()) {
if (ExplodedNode *N = C.generateSink()) {
BugType *BT = 0;
switch (msg.getMessageKind()) {
case OCM_Message:
if (!BT_msg_undef)
BT_msg_undef.reset(new BuiltinBug("Receiver in message expression "
"is an uninitialized value"));
BT = BT_msg_undef.get();
break;
case OCM_PropertyAccess:
if (!BT_objc_prop_undef)
BT_objc_prop_undef.reset(new BuiltinBug("Property access on an "
"uninitialized object "
"pointer"));
BT = BT_objc_prop_undef.get();
break;
case OCM_Subscript:
if (!BT_objc_subscript_undef)
BT_objc_subscript_undef.reset(new BuiltinBug("Subscript access on an "
"uninitialized object "
"pointer"));
BT = BT_objc_subscript_undef.get();
break;
}
assert(BT && "Unknown message kind.");
BugReport *R = new BugReport(*BT, BT->getName(), N);
const ObjCMessageExpr *ME = msg.getOriginExpr();
R->addRange(ME->getReceiverRange());
// FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
if (const Expr *ReceiverE = ME->getInstanceReceiver())
R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
ReceiverE,
R));
C.EmitReport(R);
}
return;
} else {
// Bifurcate the state into nil and non-nil ones.
DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
ProgramStateRef state = C.getState();
ProgramStateRef notNilState, nilState;
llvm::tie(notNilState, nilState) = state->assume(receiverVal);
// Handle receiver must be nil.
if (nilState && !notNilState) {
HandleNilReceiver(C, state, msg);
return;
}
}
}
示例6: checkPreObjCMessage
void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
CheckerContext &C) const {
SVal recVal = msg.getReceiverSVal();
if (recVal.isUndef()) {
if (ExplodedNode *N = C.generateErrorNode()) {
BugType *BT = nullptr;
switch (msg.getMessageKind()) {
case OCM_Message:
if (!BT_msg_undef)
BT_msg_undef.reset(new BuiltinBug(this,
"Receiver in message expression "
"is an uninitialized value"));
BT = BT_msg_undef.get();
break;
case OCM_PropertyAccess:
if (!BT_objc_prop_undef)
BT_objc_prop_undef.reset(new BuiltinBug(
this, "Property access on an uninitialized object pointer"));
BT = BT_objc_prop_undef.get();
break;
case OCM_Subscript:
if (!BT_objc_subscript_undef)
BT_objc_subscript_undef.reset(new BuiltinBug(
this, "Subscript access on an uninitialized object pointer"));
BT = BT_objc_subscript_undef.get();
break;
}
assert(BT && "Unknown message kind.");
auto R = llvm::make_unique<BugReport>(*BT, BT->getName(), N);
const ObjCMessageExpr *ME = msg.getOriginExpr();
R->addRange(ME->getReceiverRange());
// FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
if (const Expr *ReceiverE = ME->getInstanceReceiver())
bugreporter::trackExpressionValue(N, ReceiverE, *R);
C.emitReport(std::move(R));
}
return;
}
}
示例7:
/// Returns the released value if M is a call a setter that releases
/// and nils out its underlying instance variable.
SymbolRef
ObjCDeallocChecker::getValueReleasedByNillingOut(const ObjCMethodCall &M,
CheckerContext &C) const {
SVal ReceiverVal = M.getReceiverSVal();
if (!ReceiverVal.isValid())
return nullptr;
if (M.getNumArgs() == 0)
return nullptr;
if (!M.getArgExpr(0)->getType()->isObjCRetainableType())
return nullptr;
// Is the first argument nil?
SVal Arg = M.getArgSVal(0);
ProgramStateRef notNilState, nilState;
std::tie(notNilState, nilState) =
M.getState()->assume(Arg.castAs<DefinedOrUnknownSVal>());
if (!(nilState && !notNilState))
return nullptr;
const ObjCPropertyDecl *Prop = M.getAccessedProperty();
if (!Prop)
return nullptr;
ObjCIvarDecl *PropIvarDecl = Prop->getPropertyIvarDecl();
if (!PropIvarDecl)
return nullptr;
ProgramStateRef State = C.getState();
SVal LVal = State->getLValue(PropIvarDecl, ReceiverVal);
Optional<Loc> LValLoc = LVal.getAs<Loc>();
if (!LValLoc)
return nullptr;
SVal CurrentValInIvar = State->getSVal(LValLoc.getValue());
return CurrentValInIvar.getAsSymbol();
}
示例8: checkPostObjCMessage
/// This callback is used to infer the types for Class variables. This info is
/// used later to validate messages that sent to classes. Class variables are
/// initialized with by invoking the 'class' method on a class.
/// This method is also used to infer the type information for the return
/// types.
// TODO: right now it only tracks generic types. Extend this to track every
// type in the DynamicTypeMap and diagnose type errors!
void DynamicTypePropagation::checkPostObjCMessage(const ObjCMethodCall &M,
CheckerContext &C) const {
const ObjCMessageExpr *MessageExpr = M.getOriginExpr();
SymbolRef RetSym = M.getReturnValue().getAsSymbol();
if (!RetSym)
return;
Selector Sel = MessageExpr->getSelector();
ProgramStateRef State = C.getState();
// Inference for class variables.
// We are only interested in cases where the class method is invoked on a
// class. This method is provided by the runtime and available on all classes.
if (MessageExpr->getReceiverKind() == ObjCMessageExpr::Class &&
Sel.getAsString() == "class") {
QualType ReceiverType = MessageExpr->getClassReceiver();
const auto *ReceiverClassType = ReceiverType->getAs<ObjCObjectType>();
QualType ReceiverClassPointerType =
C.getASTContext().getObjCObjectPointerType(
QualType(ReceiverClassType, 0));
if (!ReceiverClassType->isSpecialized())
return;
const auto *InferredType =
ReceiverClassPointerType->getAs<ObjCObjectPointerType>();
assert(InferredType);
State = State->set<MostSpecializedTypeArgsMap>(RetSym, InferredType);
C.addTransition(State);
return;
}
// Tracking for return types.
SymbolRef RecSym = M.getReceiverSVal().getAsSymbol();
if (!RecSym)
return;
const ObjCObjectPointerType *const *TrackedType =
State->get<MostSpecializedTypeArgsMap>(RecSym);
if (!TrackedType)
return;
ASTContext &ASTCtxt = C.getASTContext();
const ObjCMethodDecl *Method =
findMethodDecl(MessageExpr, *TrackedType, ASTCtxt);
if (!Method)
return;
Optional<ArrayRef<QualType>> TypeArgs =
(*TrackedType)->getObjCSubstitutions(Method->getDeclContext());
if (!TypeArgs)
return;
QualType ResultType =
getReturnTypeForMethod(Method, *TypeArgs, *TrackedType, ASTCtxt);
// The static type is the same as the deduced type.
if (ResultType.isNull())
return;
const MemRegion *RetRegion = M.getReturnValue().getAsRegion();
ExplodedNode *Pred = C.getPredecessor();
// When there is an entry available for the return symbol in DynamicTypeMap,
// the call was inlined, and the information in the DynamicTypeMap is should
// be precise.
if (RetRegion && !State->get<DynamicTypeMap>(RetRegion)) {
// TODO: we have duplicated information in DynamicTypeMap and
// MostSpecializedTypeArgsMap. We should only store anything in the later if
// the stored data differs from the one stored in the former.
State = setDynamicTypeInfo(State, RetRegion, ResultType,
/*CanBeSubclass=*/true);
Pred = C.addTransition(State);
}
const auto *ResultPtrType = ResultType->getAs<ObjCObjectPointerType>();
if (!ResultPtrType || ResultPtrType->isUnspecialized())
return;
// When the result is a specialized type and it is not tracked yet, track it
// for the result symbol.
if (!State->get<MostSpecializedTypeArgsMap>(RetSym)) {
State = State->set<MostSpecializedTypeArgsMap>(RetSym, ResultPtrType);
C.addTransition(State, Pred);
}
}
示例9: checkPreObjCMessage
/// When the receiver has a tracked type, use that type to validate the
/// argumments of the message expression and the return value.
void DynamicTypePropagation::checkPreObjCMessage(const ObjCMethodCall &M,
CheckerContext &C) const {
ProgramStateRef State = C.getState();
SymbolRef Sym = M.getReceiverSVal().getAsSymbol();
if (!Sym)
return;
const ObjCObjectPointerType *const *TrackedType =
State->get<MostSpecializedTypeArgsMap>(Sym);
if (!TrackedType)
return;
// Get the type arguments from tracked type and substitute type arguments
// before do the semantic check.
ASTContext &ASTCtxt = C.getASTContext();
const ObjCMessageExpr *MessageExpr = M.getOriginExpr();
const ObjCMethodDecl *Method =
findMethodDecl(MessageExpr, *TrackedType, ASTCtxt);
// It is possible to call non-existent methods in Obj-C.
if (!Method)
return;
Optional<ArrayRef<QualType>> TypeArgs =
(*TrackedType)->getObjCSubstitutions(Method->getDeclContext());
// This case might happen when there is an unspecialized override of a
// specialized method.
if (!TypeArgs)
return;
for (unsigned i = 0; i < Method->param_size(); i++) {
const Expr *Arg = MessageExpr->getArg(i);
const ParmVarDecl *Param = Method->parameters()[i];
QualType OrigParamType = Param->getType();
if (!isObjCTypeParamDependent(OrigParamType))
continue;
QualType ParamType = OrigParamType.substObjCTypeArgs(
ASTCtxt, *TypeArgs, ObjCSubstitutionContext::Parameter);
// Check if it can be assigned
const auto *ParamObjectPtrType = ParamType->getAs<ObjCObjectPointerType>();
const auto *ArgObjectPtrType =
stripCastsAndSugar(Arg)->getType()->getAs<ObjCObjectPointerType>();
if (!ParamObjectPtrType || !ArgObjectPtrType)
continue;
// Check if we have more concrete tracked type that is not a super type of
// the static argument type.
SVal ArgSVal = M.getArgSVal(i);
SymbolRef ArgSym = ArgSVal.getAsSymbol();
if (ArgSym) {
const ObjCObjectPointerType *const *TrackedArgType =
State->get<MostSpecializedTypeArgsMap>(ArgSym);
if (TrackedArgType &&
ASTCtxt.canAssignObjCInterfaces(ArgObjectPtrType, *TrackedArgType)) {
ArgObjectPtrType = *TrackedArgType;
}
}
// Warn when argument is incompatible with the parameter.
if (!ASTCtxt.canAssignObjCInterfaces(ParamObjectPtrType,
ArgObjectPtrType)) {
static CheckerProgramPointTag Tag(this, "ArgTypeMismatch");
ExplodedNode *N = C.addTransition(State, &Tag);
reportGenericsBug(ArgObjectPtrType, ParamObjectPtrType, N, Sym, C, Arg);
return;
}
}
}
示例10: initIdentifierInfo
//FIXME: Consider other methods than setObject like dictionaryWithObjectsAndKeys
/// Process call to NSMutableArray:setObject:forKey:
void iOSAppSecInsecureKeyChainStorageChecker::checkPreObjCMessage
(const ObjCMethodCall &M, CheckerContext &C) const
{
MSEC_DEBUG_FUNC("redwud:","ENTER") ;
do
{
const ObjCInterfaceDecl *pRxInterface = M.getReceiverInterface() ;
if ( !pRxInterface )
{
break ;
}
ASTContext &Ctx = C.getASTContext() ;
Selector selCurr = M.getSelector() ;
initIdentifierInfo( Ctx ) ;
//TODO: Check this with property, this might not work on it
//NSMutableDictionary
if ( pRxInterface ->getIdentifier() != m_piiNSMutableDictionary )
{
break ;
}
//setObject
IdentifierInfo *piiSetObject = selCurr.getIdentifierInfoForSlot(0) ;
if ( piiSetObject != m_piiSetObject )
{
break ;
}
//forKey
IdentifierInfo *piiForKey = selCurr.getIdentifierInfoForSlot(1) ;
if ( piiForKey != m_piiForKey )
{
break ;
}
// MSEC_DEBUG("redwud: ", "'" << selCurr.getAsString() << "' num args: " << selCurr.getNumArgs() ) ;
if ( selCurr.getNumArgs() != 2 )
{
// Unlikely to be of concerned
break ;
}
ProgramStateRef pProgState = C.getState() ;
const LocationContext *pLCtx = C.getLocationContext() ;
//Get the value for "aKey" parameter (2nd)
// Checking this first because checking the first parameter takes a bit longer
const Expr *pKeyExpr = M.getArgExpr(1) ;
SVal argValKey = pProgState ->getSVal( pKeyExpr, pLCtx ) ;
if ( !CMSecCommon::isSValContains( argValKey, "kSecAttrAccessible" ) )
{
// Not of concern
break ;
}
//Get the value for "anObject" parameter (1st)
const Expr *pObjExpr = M.getArgExpr(0) ;
SVal argValAnObject = pProgState ->getSVal( pObjExpr, pLCtx ) ;
//Get receiver as symbol, should be used in either condition
SymbolRef pSymQuery = M.getReceiverSVal().getAsSymbol() ;
if ( !pSymQuery )
{
// redwud: Can't save empty receiver symbol,
// so there is no point of moving on,
// there must be something wrong with this
break ;
}
//Idea: if [query] is currently being tracked change it to different status, e.g. secure
// if not tracked add new secure state
bool bInsecureObject = isInsecureObject( argValAnObject ) ;
pProgState = pProgState ->set <StreamMap>( pSymQuery, bInsecureObject ?
KeyChainState::getNotSecure() : KeyChainState::getSecure() ) ;
// Add transition of state
//redwud: it seems that the states are transitioned at some point
C.addTransition( pProgState ) ;
MSEC_DEBUG( "redwud: ", "Finish checking!" ) ;
} while (_PASSING_) ;
MSEC_DEBUG_FUNC("redwud:","EXIT") ;
}
示例11: checkPostObjCMessage
void DanglingDelegateChecker::checkPostObjCMessage(const ObjCMethodCall &message, CheckerContext &context) const {
// if the call was inlined, there is nothing else to do
if (context.wasInlined) {
return;
}
const ObjCMessageExpr *expr = message.getOriginExpr();
if (!expr) {
assert(false);
return;
}
// want an instance message to a non-null receiver
const Expr *receiver = expr->getInstanceReceiver();
if (!receiver) {
return;
}
if (isKnownToBeNil(message.getReceiverSVal(), context)) {
// we are sure that the receiver is nil => abort mission
return;
}
// retrieves the static facts on ivars
const ObjCImplFacts *facts = getCurrentFacts(getCurrentTopClassInterface(context));
if (!facts) {
return;
}
// First we try to detect the setting of an interesting property of self
if (isObjCSelfExpr(receiver)) {
const ObjCPropertyDecl *propDecl = matchObjCMessageWithPropertySetter(*expr);
if (propDecl) {
// To mitigate false positives, we verify only setters that have an unknown body.
// (Setters with a known body are unfortunately not always inlined.)
RuntimeDefinition runtimeDefinition = message.getRuntimeDefinition();
if (!runtimeDefinition.getDecl() || runtimeDefinition.getDecl()->isImplicit()) {
verifyIvarDynamicStateAgainstStaticFacts(*expr, propDecl->getPropertyIvarDecl(), context);
}
// Next we deal with a possible assignment self.x = nil to prevent further warning
const ObjCIvarDecl *ivarDecl = propDecl->getPropertyIvarDecl();
if (ivarDecl && facts->_ivarFactsMap.find(ivarDecl) != facts->_ivarFactsMap.end()) {
SVal value = message.getArgSVal(0);
if (isKnownToBeNil(value, context)) {
// mark the corresponding ivar as cleared
ProgramStateRef state = context.getState();
IvarDynamicState clearedStateForIvar(facts->_ivarFactsMap.at(ivarDecl));
state = state->set<IvarMap>(ivarDecl, clearedStateForIvar);
context.addTransition(state);
}
}
return;
}
}
// What follows detects when we correctly clear the references inside an ivar
// This is dual to FactFinder::VisitObjCMessageExpr
StringRef selectorStr = expr->getSelector().getAsString();
// do we have a first argument equal to self?
bool paramIsSelf = isObjCSelfExpr(getArgOfObjCMessageExpr(*expr, 0));
// is the receiver an interesting ivar?
const ObjCIvarDecl *ivarDecl = matchIvarLValueExpression(*receiver);
if (ivarDecl && facts->_ivarFactsMap.find(ivarDecl) != facts->_ivarFactsMap.end()) {
// is this a release?
if (selectorStr == "release" || selectorStr == "autorelease") {
assert(!paramIsSelf);
verifyIvarDynamicStateAgainstStaticFacts(*expr, ivarDecl, context);
return;
}
// Prepare a new state to modify, associated with the receiver
ProgramStateRef state = context.getState();
// Copy the previous state if present
IvarDynamicState ivarState(state->get<IvarMap>(ivarDecl));
// is this a setter of an assign property?
const ObjCPropertyDecl *propDecl = matchObjCMessageWithPropertySetter(*expr);
if (propDecl) {
if (propDecl->getSetterKind() != ObjCPropertyDecl::Assign) {
return;
}
std::string propName = propDecl->getNameAsString();
if (!paramIsSelf) {
// the property is now considered cleared
ivarState._assignPropertyWasCleared.insert(propName);
} else {
// "unclear" the property since we just stored self again in it
ivarState._assignPropertyWasCleared.erase(propName);
}
} else if (paramIsSelf && selectorStr.startswith("removeTarget:")) {
ivarState._targetWasCleared = true;
} else if (paramIsSelf && selectorStr.startswith("removeObserver:")) {
ivarState._observerWasCleared = true;
} else {
// return to avoid transitioning to a new identical state
//.........这里部分代码省略.........