void ObjCNonNilReturnValueChecker::checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const { ProgramStateRef State = C.getState(); if (!Initialized) { ASTContext &Ctx = C.getASTContext(); ObjectAtIndex = GetUnarySelector("objectAtIndex", Ctx); ObjectAtIndexedSubscript = GetUnarySelector("objectAtIndexedSubscript", Ctx); NullSelector = GetNullarySelector("null", Ctx); } // Check the receiver type. if (const ObjCInterfaceDecl *Interface = M.getReceiverInterface()) { // Assume that object returned from '[self init]' or '[super init]' is not // 'nil' if we are processing an inlined function/method. // // A defensive callee will (and should) check if the object returned by // '[super init]' is 'nil' before doing it's own initialization. However, // since 'nil' is rarely returned in practice, we should not warn when the // caller to the defensive constructor uses the object in contexts where // 'nil' is not accepted. if (!C.inTopFrame() && M.getDecl() && M.getDecl()->getMethodFamily() == OMF_init && M.isReceiverSelfOrSuper()) { State = assumeExprIsNonNull(M.getOriginExpr(), State, C); } FoundationClass Cl = findKnownClass(Interface); // Objects returned from // [NSArray|NSOrderedSet]::[ObjectAtIndex|ObjectAtIndexedSubscript] // are never 'nil'. if (Cl == FC_NSArray || Cl == FC_NSOrderedSet) { Selector Sel = M.getSelector(); if (Sel == ObjectAtIndex || Sel == ObjectAtIndexedSubscript) { // Go ahead and assume the value is non-nil. State = assumeExprIsNonNull(M.getOriginExpr(), State, C); } } // Objects returned from [NSNull null] are not nil. if (Cl == FC_NSNull) { if (M.getSelector() == NullSelector) { // Go ahead and assume the value is non-nil. State = assumeExprIsNonNull(M.getOriginExpr(), State, C); } } } C.addTransition(State); }