bool ObjCSuperDeallocChecker::isSuperDeallocMessage(const ObjCMethodCall &M) const { if (M.getOriginExpr()->getReceiverKind() != ObjCMessageExpr::SuperInstance) return false; ASTContext &Ctx = M.getState()->getStateManager().getContext(); initIdentifierInfoAndSelectors(Ctx); return M.getSelector() == SELdealloc; }
/// 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(); }