本文整理汇总了C++中ObjCMethodCall::getReturnValue方法的典型用法代码示例。如果您正苦于以下问题:C++ ObjCMethodCall::getReturnValue方法的具体用法?C++ ObjCMethodCall::getReturnValue怎么用?C++ ObjCMethodCall::getReturnValue使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ObjCMethodCall
的用法示例。
在下文中一共展示了ObjCMethodCall::getReturnValue方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: 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);
}
}
示例2: checkPostObjCMessage
/// Calculate the nullability of the result of a message expr based on the
/// nullability of the receiver, the nullability of the return value, and the
/// constraints.
void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M,
CheckerContext &C) const {
auto Decl = M.getDecl();
if (!Decl)
return;
QualType RetType = Decl->getReturnType();
if (!RetType->isAnyPointerType())
return;
ProgramStateRef State = C.getState();
if (State->get<PreconditionViolated>())
return;
const MemRegion *ReturnRegion = getTrackRegion(M.getReturnValue());
if (!ReturnRegion)
return;
auto Interface = Decl->getClassInterface();
auto Name = Interface ? Interface->getName() : "";
// In order to reduce the noise in the diagnostics generated by this checker,
// some framework and programming style based heuristics are used. These
// heuristics are for Cocoa APIs which have NS prefix.
if (Name.startswith("NS")) {
// Developers rely on dynamic invariants such as an item should be available
// in a collection, or a collection is not empty often. Those invariants can
// not be inferred by any static analysis tool. To not to bother the users
// with too many false positives, every item retrieval function should be
// ignored for collections. The instance methods of dictionaries in Cocoa
// are either item retrieval related or not interesting nullability wise.
// Using this fact, to keep the code easier to read just ignore the return
// value of every instance method of dictionaries.
if (M.isInstanceMessage() && Name.find("Dictionary") != StringRef::npos) {
State =
State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
C.addTransition(State);
return;
}
// For similar reasons ignore some methods of Cocoa arrays.
StringRef FirstSelectorSlot = M.getSelector().getNameForSlot(0);
if (Name.find("Array") != StringRef::npos &&
(FirstSelectorSlot == "firstObject" ||
FirstSelectorSlot == "lastObject")) {
State =
State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
C.addTransition(State);
return;
}
// Encoding related methods of string should not fail when lossless
// encodings are used. Using lossless encodings is so frequent that ignoring
// this class of methods reduced the emitted diagnostics by about 30% on
// some projects (and all of that was false positives).
if (Name.find("String") != StringRef::npos) {
for (auto Param : M.parameters()) {
if (Param->getName() == "encoding") {
State = State->set<NullabilityMap>(ReturnRegion,
Nullability::Contradicted);
C.addTransition(State);
return;
}
}
}
}
const ObjCMessageExpr *Message = M.getOriginExpr();
Nullability SelfNullability = getReceiverNullability(M, State);
const NullabilityState *NullabilityOfReturn =
State->get<NullabilityMap>(ReturnRegion);
if (NullabilityOfReturn) {
// When we have a nullability tracked for the return value, the nullability
// of the expression will be the most nullable of the receiver and the
// return value.
Nullability RetValTracked = NullabilityOfReturn->getValue();
Nullability ComputedNullab =
getMostNullable(RetValTracked, SelfNullability);
if (ComputedNullab != RetValTracked &&
ComputedNullab != Nullability::Unspecified) {
const Stmt *NullabilitySource =
ComputedNullab == RetValTracked
? NullabilityOfReturn->getNullabilitySource()
: Message->getInstanceReceiver();
State = State->set<NullabilityMap>(
ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
C.addTransition(State);
}
return;
}
// No tracked information. Use static type information for return value.
Nullability RetNullability = getNullabilityAnnotation(RetType);
// Properties might be computed. For this reason the static analyzer creates a
// new symbol each time an unknown property is read. To avoid false pozitives
// do not treat unknown properties as nullable, even when they explicitly
// marked nullable.
//.........这里部分代码省略.........