Home | History | Annotate | Line # | Download | only in RetainCountChecker
      1 //==-- RetainCountChecker.cpp - Checks for leaks and other issues -*- C++ -*--//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 //  This file defines the methods for RetainCountChecker, which implements
     10 //  a reference count checker for Core Foundation and Cocoa on (Mac OS X).
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "RetainCountChecker.h"
     15 #include "clang/StaticAnalyzer/Core/Checker.h"
     16 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
     17 
     18 using namespace clang;
     19 using namespace ento;
     20 using namespace retaincountchecker;
     21 
     22 REGISTER_MAP_WITH_PROGRAMSTATE(RefBindings, SymbolRef, RefVal)
     23 
     24 namespace clang {
     25 namespace ento {
     26 namespace retaincountchecker {
     27 
     28 const RefVal *getRefBinding(ProgramStateRef State, SymbolRef Sym) {
     29   return State->get<RefBindings>(Sym);
     30 }
     31 
     32 } // end namespace retaincountchecker
     33 } // end namespace ento
     34 } // end namespace clang
     35 
     36 static ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
     37                                      RefVal Val) {
     38   assert(Sym != nullptr);
     39   return State->set<RefBindings>(Sym, Val);
     40 }
     41 
     42 static ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
     43   return State->remove<RefBindings>(Sym);
     44 }
     45 
     46 void RefVal::print(raw_ostream &Out) const {
     47   if (!T.isNull())
     48     Out << "Tracked " << T.getAsString() << " | ";
     49 
     50   switch (getKind()) {
     51     default: llvm_unreachable("Invalid RefVal kind");
     52     case Owned: {
     53       Out << "Owned";
     54       unsigned cnt = getCount();
     55       if (cnt) Out << " (+ " << cnt << ")";
     56       break;
     57     }
     58 
     59     case NotOwned: {
     60       Out << "NotOwned";
     61       unsigned cnt = getCount();
     62       if (cnt) Out << " (+ " << cnt << ")";
     63       break;
     64     }
     65 
     66     case ReturnedOwned: {
     67       Out << "ReturnedOwned";
     68       unsigned cnt = getCount();
     69       if (cnt) Out << " (+ " << cnt << ")";
     70       break;
     71     }
     72 
     73     case ReturnedNotOwned: {
     74       Out << "ReturnedNotOwned";
     75       unsigned cnt = getCount();
     76       if (cnt) Out << " (+ " << cnt << ")";
     77       break;
     78     }
     79 
     80     case Released:
     81       Out << "Released";
     82       break;
     83 
     84     case ErrorDeallocNotOwned:
     85       Out << "-dealloc (not-owned)";
     86       break;
     87 
     88     case ErrorLeak:
     89       Out << "Leaked";
     90       break;
     91 
     92     case ErrorLeakReturned:
     93       Out << "Leaked (Bad naming)";
     94       break;
     95 
     96     case ErrorUseAfterRelease:
     97       Out << "Use-After-Release [ERROR]";
     98       break;
     99 
    100     case ErrorReleaseNotOwned:
    101       Out << "Release of Not-Owned [ERROR]";
    102       break;
    103 
    104     case RefVal::ErrorOverAutorelease:
    105       Out << "Over-autoreleased";
    106       break;
    107 
    108     case RefVal::ErrorReturnedNotOwned:
    109       Out << "Non-owned object returned instead of owned";
    110       break;
    111   }
    112 
    113   switch (getIvarAccessHistory()) {
    114   case IvarAccessHistory::None:
    115     break;
    116   case IvarAccessHistory::AccessedDirectly:
    117     Out << " [direct ivar access]";
    118     break;
    119   case IvarAccessHistory::ReleasedAfterDirectAccess:
    120     Out << " [released after direct ivar access]";
    121   }
    122 
    123   if (ACnt) {
    124     Out << " [autorelease -" << ACnt << ']';
    125   }
    126 }
    127 
    128 namespace {
    129 class StopTrackingCallback final : public SymbolVisitor {
    130   ProgramStateRef state;
    131 public:
    132   StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
    133   ProgramStateRef getState() const { return state; }
    134 
    135   bool VisitSymbol(SymbolRef sym) override {
    136     state = removeRefBinding(state, sym);
    137     return true;
    138   }
    139 };
    140 } // end anonymous namespace
    141 
    142 //===----------------------------------------------------------------------===//
    143 // Handle statements that may have an effect on refcounts.
    144 //===----------------------------------------------------------------------===//
    145 
    146 void RetainCountChecker::checkPostStmt(const BlockExpr *BE,
    147                                        CheckerContext &C) const {
    148 
    149   // Scan the BlockDecRefExprs for any object the retain count checker
    150   // may be tracking.
    151   if (!BE->getBlockDecl()->hasCaptures())
    152     return;
    153 
    154   ProgramStateRef state = C.getState();
    155   auto *R = cast<BlockDataRegion>(C.getSVal(BE).getAsRegion());
    156 
    157   BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
    158                                             E = R->referenced_vars_end();
    159 
    160   if (I == E)
    161     return;
    162 
    163   // FIXME: For now we invalidate the tracking of all symbols passed to blocks
    164   // via captured variables, even though captured variables result in a copy
    165   // and in implicit increment/decrement of a retain count.
    166   SmallVector<const MemRegion*, 10> Regions;
    167   const LocationContext *LC = C.getLocationContext();
    168   MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
    169 
    170   for ( ; I != E; ++I) {
    171     const VarRegion *VR = I.getCapturedRegion();
    172     if (VR->getSuperRegion() == R) {
    173       VR = MemMgr.getVarRegion(VR->getDecl(), LC);
    174     }
    175     Regions.push_back(VR);
    176   }
    177 
    178   state = state->scanReachableSymbols<StopTrackingCallback>(Regions).getState();
    179   C.addTransition(state);
    180 }
    181 
    182 void RetainCountChecker::checkPostStmt(const CastExpr *CE,
    183                                        CheckerContext &C) const {
    184   const ObjCBridgedCastExpr *BE = dyn_cast<ObjCBridgedCastExpr>(CE);
    185   if (!BE)
    186     return;
    187 
    188   QualType QT = CE->getType();
    189   ObjKind K;
    190   if (QT->isObjCObjectPointerType()) {
    191     K = ObjKind::ObjC;
    192   } else {
    193     K = ObjKind::CF;
    194   }
    195 
    196   ArgEffect AE = ArgEffect(IncRef, K);
    197 
    198   switch (BE->getBridgeKind()) {
    199     case OBC_Bridge:
    200       // Do nothing.
    201       return;
    202     case OBC_BridgeRetained:
    203       AE = AE.withKind(IncRef);
    204       break;
    205     case OBC_BridgeTransfer:
    206       AE = AE.withKind(DecRefBridgedTransferred);
    207       break;
    208   }
    209 
    210   ProgramStateRef state = C.getState();
    211   SymbolRef Sym = C.getSVal(CE).getAsLocSymbol();
    212   if (!Sym)
    213     return;
    214   const RefVal* T = getRefBinding(state, Sym);
    215   if (!T)
    216     return;
    217 
    218   RefVal::Kind hasErr = (RefVal::Kind) 0;
    219   state = updateSymbol(state, Sym, *T, AE, hasErr, C);
    220 
    221   if (hasErr) {
    222     // FIXME: If we get an error during a bridge cast, should we report it?
    223     return;
    224   }
    225 
    226   C.addTransition(state);
    227 }
    228 
    229 void RetainCountChecker::processObjCLiterals(CheckerContext &C,
    230                                              const Expr *Ex) const {
    231   ProgramStateRef state = C.getState();
    232   const ExplodedNode *pred = C.getPredecessor();
    233   for (const Stmt *Child : Ex->children()) {
    234     SVal V = pred->getSVal(Child);
    235     if (SymbolRef sym = V.getAsSymbol())
    236       if (const RefVal* T = getRefBinding(state, sym)) {
    237         RefVal::Kind hasErr = (RefVal::Kind) 0;
    238         state = updateSymbol(state, sym, *T,
    239                              ArgEffect(MayEscape, ObjKind::ObjC), hasErr, C);
    240         if (hasErr) {
    241           processNonLeakError(state, Child->getSourceRange(), hasErr, sym, C);
    242           return;
    243         }
    244       }
    245   }
    246 
    247   // Return the object as autoreleased.
    248   //  RetEffect RE = RetEffect::MakeNotOwned(ObjKind::ObjC);
    249   if (SymbolRef sym =
    250         state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
    251     QualType ResultTy = Ex->getType();
    252     state = setRefBinding(state, sym,
    253                           RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
    254   }
    255 
    256   C.addTransition(state);
    257 }
    258 
    259 void RetainCountChecker::checkPostStmt(const ObjCArrayLiteral *AL,
    260                                        CheckerContext &C) const {
    261   // Apply the 'MayEscape' to all values.
    262   processObjCLiterals(C, AL);
    263 }
    264 
    265 void RetainCountChecker::checkPostStmt(const ObjCDictionaryLiteral *DL,
    266                                        CheckerContext &C) const {
    267   // Apply the 'MayEscape' to all keys and values.
    268   processObjCLiterals(C, DL);
    269 }
    270 
    271 void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
    272                                        CheckerContext &C) const {
    273   const ExplodedNode *Pred = C.getPredecessor();
    274   ProgramStateRef State = Pred->getState();
    275 
    276   if (SymbolRef Sym = Pred->getSVal(Ex).getAsSymbol()) {
    277     QualType ResultTy = Ex->getType();
    278     State = setRefBinding(State, Sym,
    279                           RefVal::makeNotOwned(ObjKind::ObjC, ResultTy));
    280   }
    281 
    282   C.addTransition(State);
    283 }
    284 
    285 void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
    286                                        CheckerContext &C) const {
    287   Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>();
    288   if (!IVarLoc)
    289     return;
    290 
    291   ProgramStateRef State = C.getState();
    292   SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
    293   if (!Sym || !dyn_cast_or_null<ObjCIvarRegion>(Sym->getOriginRegion()))
    294     return;
    295 
    296   // Accessing an ivar directly is unusual. If we've done that, be more
    297   // forgiving about what the surrounding code is allowed to do.
    298 
    299   QualType Ty = Sym->getType();
    300   ObjKind Kind;
    301   if (Ty->isObjCRetainableType())
    302     Kind = ObjKind::ObjC;
    303   else if (coreFoundation::isCFObjectRef(Ty))
    304     Kind = ObjKind::CF;
    305   else
    306     return;
    307 
    308   // If the value is already known to be nil, don't bother tracking it.
    309   ConstraintManager &CMgr = State->getConstraintManager();
    310   if (CMgr.isNull(State, Sym).isConstrainedTrue())
    311     return;
    312 
    313   if (const RefVal *RV = getRefBinding(State, Sym)) {
    314     // If we've seen this symbol before, or we're only seeing it now because
    315     // of something the analyzer has synthesized, don't do anything.
    316     if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None ||
    317         isSynthesizedAccessor(C.getStackFrame())) {
    318       return;
    319     }
    320 
    321     // Note that this value has been loaded from an ivar.
    322     C.addTransition(setRefBinding(State, Sym, RV->withIvarAccess()));
    323     return;
    324   }
    325 
    326   RefVal PlusZero = RefVal::makeNotOwned(Kind, Ty);
    327 
    328   // In a synthesized accessor, the effective retain count is +0.
    329   if (isSynthesizedAccessor(C.getStackFrame())) {
    330     C.addTransition(setRefBinding(State, Sym, PlusZero));
    331     return;
    332   }
    333 
    334   State = setRefBinding(State, Sym, PlusZero.withIvarAccess());
    335   C.addTransition(State);
    336 }
    337 
    338 static bool isReceiverUnconsumedSelf(const CallEvent &Call) {
    339   if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
    340 
    341     // Check if the message is not consumed, we know it will not be used in
    342     // an assignment, ex: "self = [super init]".
    343     return MC->getMethodFamily() == OMF_init && MC->isReceiverSelfOrSuper() &&
    344            !Call.getLocationContext()
    345                 ->getAnalysisDeclContext()
    346                 ->getParentMap()
    347                 .isConsumedExpr(Call.getOriginExpr());
    348   }
    349   return false;
    350 }
    351 
    352 const static RetainSummary *getSummary(RetainSummaryManager &Summaries,
    353                                        const CallEvent &Call,
    354                                        QualType ReceiverType) {
    355   const Expr *CE = Call.getOriginExpr();
    356   AnyCall C =
    357       CE ? *AnyCall::forExpr(CE)
    358          : AnyCall(cast<CXXDestructorDecl>(Call.getDecl()));
    359   return Summaries.getSummary(C, Call.hasNonZeroCallbackArg(),
    360                               isReceiverUnconsumedSelf(Call), ReceiverType);
    361 }
    362 
    363 void RetainCountChecker::checkPostCall(const CallEvent &Call,
    364                                        CheckerContext &C) const {
    365   RetainSummaryManager &Summaries = getSummaryManager(C);
    366 
    367   // Leave null if no receiver.
    368   QualType ReceiverType;
    369   if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
    370     if (MC->isInstanceMessage()) {
    371       SVal ReceiverV = MC->getReceiverSVal();
    372       if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
    373         if (const RefVal *T = getRefBinding(C.getState(), Sym))
    374           ReceiverType = T->getType();
    375     }
    376   }
    377 
    378   const RetainSummary *Summ = getSummary(Summaries, Call, ReceiverType);
    379 
    380   if (C.wasInlined) {
    381     processSummaryOfInlined(*Summ, Call, C);
    382     return;
    383   }
    384   checkSummary(*Summ, Call, C);
    385 }
    386 
    387 /// GetReturnType - Used to get the return type of a message expression or
    388 ///  function call with the intention of affixing that type to a tracked symbol.
    389 ///  While the return type can be queried directly from RetEx, when
    390 ///  invoking class methods we augment to the return type to be that of
    391 ///  a pointer to the class (as opposed it just being id).
    392 // FIXME: We may be able to do this with related result types instead.
    393 // This function is probably overestimating.
    394 static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) {
    395   QualType RetTy = RetE->getType();
    396   // If RetE is not a message expression just return its type.
    397   // If RetE is a message expression, return its types if it is something
    398   /// more specific than id.
    399   if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
    400     if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>())
    401       if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
    402           PT->isObjCClassType()) {
    403         // At this point we know the return type of the message expression is
    404         // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
    405         // is a call to a class method whose type we can resolve.  In such
    406         // cases, promote the return type to XXX* (where XXX is the class).
    407         const ObjCInterfaceDecl *D = ME->getReceiverInterface();
    408         return !D ? RetTy :
    409                     Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D));
    410       }
    411 
    412   return RetTy;
    413 }
    414 
    415 static Optional<RefVal> refValFromRetEffect(RetEffect RE,
    416                                             QualType ResultTy) {
    417   if (RE.isOwned()) {
    418     return RefVal::makeOwned(RE.getObjKind(), ResultTy);
    419   } else if (RE.notOwned()) {
    420     return RefVal::makeNotOwned(RE.getObjKind(), ResultTy);
    421   }
    422 
    423   return None;
    424 }
    425 
    426 static bool isPointerToObject(QualType QT) {
    427   QualType PT = QT->getPointeeType();
    428   if (!PT.isNull())
    429     if (PT->getAsCXXRecordDecl())
    430       return true;
    431   return false;
    432 }
    433 
    434 /// Whether the tracked value should be escaped on a given call.
    435 /// OSObjects are escaped when passed to void * / etc.
    436 static bool shouldEscapeOSArgumentOnCall(const CallEvent &CE, unsigned ArgIdx,
    437                                        const RefVal *TrackedValue) {
    438   if (TrackedValue->getObjKind() != ObjKind::OS)
    439     return false;
    440   if (ArgIdx >= CE.parameters().size())
    441     return false;
    442   return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
    443 }
    444 
    445 // We don't always get the exact modeling of the function with regards to the
    446 // retain count checker even when the function is inlined. For example, we need
    447 // to stop tracking the symbols which were marked with StopTrackingHard.
    448 void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
    449                                                  const CallEvent &CallOrMsg,
    450                                                  CheckerContext &C) const {
    451   ProgramStateRef state = C.getState();
    452 
    453   // Evaluate the effect of the arguments.
    454   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
    455     SVal V = CallOrMsg.getArgSVal(idx);
    456 
    457     if (SymbolRef Sym = V.getAsLocSymbol()) {
    458       bool ShouldRemoveBinding = Summ.getArg(idx).getKind() == StopTrackingHard;
    459       if (const RefVal *T = getRefBinding(state, Sym))
    460         if (shouldEscapeOSArgumentOnCall(CallOrMsg, idx, T))
    461           ShouldRemoveBinding = true;
    462 
    463       if (ShouldRemoveBinding)
    464         state = removeRefBinding(state, Sym);
    465     }
    466   }
    467 
    468   // Evaluate the effect on the message receiver.
    469   if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
    470     if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
    471       if (Summ.getReceiverEffect().getKind() == StopTrackingHard) {
    472         state = removeRefBinding(state, Sym);
    473       }
    474     }
    475   }
    476 
    477   // Consult the summary for the return value.
    478   RetEffect RE = Summ.getRetEffect();
    479 
    480   if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
    481     if (RE.getKind() == RetEffect::NoRetHard)
    482       state = removeRefBinding(state, Sym);
    483   }
    484 
    485   C.addTransition(state);
    486 }
    487 
    488 static bool isSmartPtrField(const MemRegion *MR) {
    489   const auto *TR = dyn_cast<TypedValueRegion>(
    490     cast<SubRegion>(MR)->getSuperRegion());
    491   return TR && RetainSummaryManager::isKnownSmartPointer(TR->getValueType());
    492 }
    493 
    494 
    495 /// A value escapes in these possible cases:
    496 ///
    497 /// - binding to something that is not a memory region.
    498 /// - binding to a memregion that does not have stack storage
    499 /// - binding to a variable that has a destructor attached using CleanupAttr
    500 ///
    501 /// We do not currently model what happens when a symbol is
    502 /// assigned to a struct field, unless it is a known smart pointer
    503 /// implementation, about which we know that it is inlined.
    504 /// FIXME: This could definitely be improved upon.
    505 static bool shouldEscapeRegion(const MemRegion *R) {
    506   if (isSmartPtrField(R))
    507     return false;
    508 
    509   const auto *VR = dyn_cast<VarRegion>(R);
    510 
    511   if (!R->hasStackStorage() || !VR)
    512     return true;
    513 
    514   const VarDecl *VD = VR->getDecl();
    515   if (!VD->hasAttr<CleanupAttr>())
    516     return false; // CleanupAttr attaches destructors, which cause escaping.
    517   return true;
    518 }
    519 
    520 static SmallVector<ProgramStateRef, 2>
    521 updateOutParameters(ProgramStateRef State, const RetainSummary &Summ,
    522                     const CallEvent &CE) {
    523 
    524   SVal L = CE.getReturnValue();
    525 
    526   // Splitting is required to support out parameters,
    527   // as out parameters might be created only on the "success" branch.
    528   // We want to avoid eagerly splitting unless out parameters are actually
    529   // needed.
    530   bool SplitNecessary = false;
    531   for (auto &P : Summ.getArgEffects())
    532     if (P.second.getKind() == RetainedOutParameterOnNonZero ||
    533         P.second.getKind() == RetainedOutParameterOnZero)
    534       SplitNecessary = true;
    535 
    536   ProgramStateRef AssumeNonZeroReturn = State;
    537   ProgramStateRef AssumeZeroReturn = State;
    538 
    539   if (SplitNecessary) {
    540     if (!CE.getResultType()->isScalarType()) {
    541       // Structures cannot be assumed. This probably deserves
    542       // a compiler warning for invalid annotations.
    543       return {State};
    544     }
    545     if (auto DL = L.getAs<DefinedOrUnknownSVal>()) {
    546       AssumeNonZeroReturn = AssumeNonZeroReturn->assume(*DL, true);
    547       AssumeZeroReturn = AssumeZeroReturn->assume(*DL, false);
    548     }
    549   }
    550 
    551   for (unsigned idx = 0, e = CE.getNumArgs(); idx != e; ++idx) {
    552     SVal ArgVal = CE.getArgSVal(idx);
    553     ArgEffect AE = Summ.getArg(idx);
    554 
    555     auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.getAsRegion());
    556     if (!ArgRegion)
    557       continue;
    558 
    559     QualType PointeeTy = ArgRegion->getValueType();
    560     SVal PointeeVal = State->getSVal(ArgRegion);
    561     SymbolRef Pointee = PointeeVal.getAsLocSymbol();
    562     if (!Pointee)
    563       continue;
    564 
    565     if (shouldEscapeRegion(ArgRegion))
    566       continue;
    567 
    568     auto makeNotOwnedParameter = [&](ProgramStateRef St) {
    569       return setRefBinding(St, Pointee,
    570                            RefVal::makeNotOwned(AE.getObjKind(), PointeeTy));
    571     };
    572     auto makeOwnedParameter = [&](ProgramStateRef St) {
    573       return setRefBinding(St, Pointee,
    574                            RefVal::makeOwned(ObjKind::OS, PointeeTy));
    575     };
    576 
    577     switch (AE.getKind()) {
    578     case UnretainedOutParameter:
    579       AssumeNonZeroReturn = makeNotOwnedParameter(AssumeNonZeroReturn);
    580       AssumeZeroReturn = makeNotOwnedParameter(AssumeZeroReturn);
    581       break;
    582     case RetainedOutParameter:
    583       AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
    584       AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
    585       break;
    586     case RetainedOutParameterOnNonZero:
    587       AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
    588       break;
    589     case RetainedOutParameterOnZero:
    590       AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
    591       break;
    592     default:
    593       break;
    594     }
    595   }
    596 
    597   if (SplitNecessary) {
    598     return {AssumeNonZeroReturn, AssumeZeroReturn};
    599   } else {
    600     assert(AssumeZeroReturn == AssumeNonZeroReturn);
    601     return {AssumeZeroReturn};
    602   }
    603 }
    604 
    605 void RetainCountChecker::checkSummary(const RetainSummary &Summ,
    606                                       const CallEvent &CallOrMsg,
    607                                       CheckerContext &C) const {
    608   ProgramStateRef state = C.getState();
    609 
    610   // Evaluate the effect of the arguments.
    611   RefVal::Kind hasErr = (RefVal::Kind) 0;
    612   SourceRange ErrorRange;
    613   SymbolRef ErrorSym = nullptr;
    614 
    615   // Helper tag for providing diagnostics: indicate whether dealloc was sent
    616   // at this location.
    617   bool DeallocSent = false;
    618 
    619   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
    620     SVal V = CallOrMsg.getArgSVal(idx);
    621 
    622     ArgEffect Effect = Summ.getArg(idx);
    623     if (SymbolRef Sym = V.getAsLocSymbol()) {
    624       if (const RefVal *T = getRefBinding(state, Sym)) {
    625 
    626         if (shouldEscapeOSArgumentOnCall(CallOrMsg, idx, T))
    627           Effect = ArgEffect(StopTrackingHard, ObjKind::OS);
    628 
    629         state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
    630         if (hasErr) {
    631           ErrorRange = CallOrMsg.getArgSourceRange(idx);
    632           ErrorSym = Sym;
    633           break;
    634         } else if (Effect.getKind() == Dealloc) {
    635           DeallocSent = true;
    636         }
    637       }
    638     }
    639   }
    640 
    641   // Evaluate the effect on the message receiver / `this` argument.
    642   bool ReceiverIsTracked = false;
    643   if (!hasErr) {
    644     if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
    645       if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
    646         if (const RefVal *T = getRefBinding(state, Sym)) {
    647           ReceiverIsTracked = true;
    648           state = updateSymbol(state, Sym, *T,
    649                                Summ.getReceiverEffect(), hasErr, C);
    650           if (hasErr) {
    651             ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
    652             ErrorSym = Sym;
    653           } else if (Summ.getReceiverEffect().getKind() == Dealloc) {
    654             DeallocSent = true;
    655           }
    656         }
    657       }
    658     } else if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
    659       if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
    660         if (const RefVal *T = getRefBinding(state, Sym)) {
    661           state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
    662                                hasErr, C);
    663           if (hasErr) {
    664             ErrorRange = MCall->getOriginExpr()->getSourceRange();
    665             ErrorSym = Sym;
    666           }
    667         }
    668       }
    669     }
    670   }
    671 
    672   // Process any errors.
    673   if (hasErr) {
    674     processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C);
    675     return;
    676   }
    677 
    678   // Consult the summary for the return value.
    679   RetEffect RE = Summ.getRetEffect();
    680 
    681   if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
    682     if (ReceiverIsTracked)
    683       RE = getSummaryManager(C).getObjAllocRetEffect();
    684     else
    685       RE = RetEffect::MakeNoRet();
    686   }
    687 
    688   if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
    689     QualType ResultTy = CallOrMsg.getResultType();
    690     if (RE.notOwned()) {
    691       const Expr *Ex = CallOrMsg.getOriginExpr();
    692       assert(Ex);
    693       ResultTy = GetReturnType(Ex, C.getASTContext());
    694     }
    695     if (Optional<RefVal> updatedRefVal = refValFromRetEffect(RE, ResultTy))
    696       state = setRefBinding(state, Sym, *updatedRefVal);
    697   }
    698 
    699   SmallVector<ProgramStateRef, 2> Out =
    700       updateOutParameters(state, Summ, CallOrMsg);
    701 
    702   for (ProgramStateRef St : Out) {
    703     if (DeallocSent) {
    704       C.addTransition(St, C.getPredecessor(), &getDeallocSentTag());
    705     } else {
    706       C.addTransition(St);
    707     }
    708   }
    709 }
    710 
    711 ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
    712                                                  SymbolRef sym, RefVal V,
    713                                                  ArgEffect AE,
    714                                                  RefVal::Kind &hasErr,
    715                                                  CheckerContext &C) const {
    716   bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
    717   if (AE.getObjKind() == ObjKind::ObjC && IgnoreRetainMsg) {
    718     switch (AE.getKind()) {
    719     default:
    720       break;
    721     case IncRef:
    722       AE = AE.withKind(DoNothing);
    723       break;
    724     case DecRef:
    725       AE = AE.withKind(DoNothing);
    726       break;
    727     case DecRefAndStopTrackingHard:
    728       AE = AE.withKind(StopTracking);
    729       break;
    730     }
    731   }
    732 
    733   // Handle all use-after-releases.
    734   if (V.getKind() == RefVal::Released) {
    735     V = V ^ RefVal::ErrorUseAfterRelease;
    736     hasErr = V.getKind();
    737     return setRefBinding(state, sym, V);
    738   }
    739 
    740   switch (AE.getKind()) {
    741     case UnretainedOutParameter:
    742     case RetainedOutParameter:
    743     case RetainedOutParameterOnZero:
    744     case RetainedOutParameterOnNonZero:
    745       llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
    746                        "not have ref state.");
    747 
    748     case Dealloc: // NB. we only need to add a note in a non-error case.
    749       switch (V.getKind()) {
    750         default:
    751           llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
    752         case RefVal::Owned:
    753           // The object immediately transitions to the released state.
    754           V = V ^ RefVal::Released;
    755           V.clearCounts();
    756           return setRefBinding(state, sym, V);
    757         case RefVal::NotOwned:
    758           V = V ^ RefVal::ErrorDeallocNotOwned;
    759           hasErr = V.getKind();
    760           break;
    761       }
    762       break;
    763 
    764     case MayEscape:
    765       if (V.getKind() == RefVal::Owned) {
    766         V = V ^ RefVal::NotOwned;
    767         break;
    768       }
    769 
    770       LLVM_FALLTHROUGH;
    771 
    772     case DoNothing:
    773       return state;
    774 
    775     case Autorelease:
    776       // Update the autorelease counts.
    777       V = V.autorelease();
    778       break;
    779 
    780     case StopTracking:
    781     case StopTrackingHard:
    782       return removeRefBinding(state, sym);
    783 
    784     case IncRef:
    785       switch (V.getKind()) {
    786         default:
    787           llvm_unreachable("Invalid RefVal state for a retain.");
    788         case RefVal::Owned:
    789         case RefVal::NotOwned:
    790           V = V + 1;
    791           break;
    792       }
    793       break;
    794 
    795     case DecRef:
    796     case DecRefBridgedTransferred:
    797     case DecRefAndStopTrackingHard:
    798       switch (V.getKind()) {
    799         default:
    800           // case 'RefVal::Released' handled above.
    801           llvm_unreachable("Invalid RefVal state for a release.");
    802 
    803         case RefVal::Owned:
    804           assert(V.getCount() > 0);
    805           if (V.getCount() == 1) {
    806             if (AE.getKind() == DecRefBridgedTransferred ||
    807                 V.getIvarAccessHistory() ==
    808                   RefVal::IvarAccessHistory::AccessedDirectly)
    809               V = V ^ RefVal::NotOwned;
    810             else
    811               V = V ^ RefVal::Released;
    812           } else if (AE.getKind() == DecRefAndStopTrackingHard) {
    813             return removeRefBinding(state, sym);
    814           }
    815 
    816           V = V - 1;
    817           break;
    818 
    819         case RefVal::NotOwned:
    820           if (V.getCount() > 0) {
    821             if (AE.getKind() == DecRefAndStopTrackingHard)
    822               return removeRefBinding(state, sym);
    823             V = V - 1;
    824           } else if (V.getIvarAccessHistory() ==
    825                        RefVal::IvarAccessHistory::AccessedDirectly) {
    826             // Assume that the instance variable was holding on the object at
    827             // +1, and we just didn't know.
    828             if (AE.getKind() == DecRefAndStopTrackingHard)
    829               return removeRefBinding(state, sym);
    830             V = V.releaseViaIvar() ^ RefVal::Released;
    831           } else {
    832             V = V ^ RefVal::ErrorReleaseNotOwned;
    833             hasErr = V.getKind();
    834           }
    835           break;
    836       }
    837       break;
    838   }
    839   return setRefBinding(state, sym, V);
    840 }
    841 
    842 const RefCountBug &
    843 RetainCountChecker::errorKindToBugKind(RefVal::Kind ErrorKind,
    844                                        SymbolRef Sym) const {
    845   switch (ErrorKind) {
    846     case RefVal::ErrorUseAfterRelease:
    847       return *UseAfterRelease;
    848     case RefVal::ErrorReleaseNotOwned:
    849       return *ReleaseNotOwned;
    850     case RefVal::ErrorDeallocNotOwned:
    851       if (Sym->getType()->getPointeeCXXRecordDecl())
    852         return *FreeNotOwned;
    853       return *DeallocNotOwned;
    854     default:
    855       llvm_unreachable("Unhandled error.");
    856   }
    857 }
    858 
    859 void RetainCountChecker::processNonLeakError(ProgramStateRef St,
    860                                              SourceRange ErrorRange,
    861                                              RefVal::Kind ErrorKind,
    862                                              SymbolRef Sym,
    863                                              CheckerContext &C) const {
    864   // HACK: Ignore retain-count issues on values accessed through ivars,
    865   // because of cases like this:
    866   //   [_contentView retain];
    867   //   [_contentView removeFromSuperview];
    868   //   [self addSubview:_contentView]; // invalidates 'self'
    869   //   [_contentView release];
    870   if (const RefVal *RV = getRefBinding(St, Sym))
    871     if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
    872       return;
    873 
    874   ExplodedNode *N = C.generateErrorNode(St);
    875   if (!N)
    876     return;
    877 
    878   auto report = std::make_unique<RefCountReport>(
    879       errorKindToBugKind(ErrorKind, Sym),
    880       C.getASTContext().getLangOpts(), N, Sym);
    881   report->addRange(ErrorRange);
    882   C.emitReport(std::move(report));
    883 }
    884 
    885 //===----------------------------------------------------------------------===//
    886 // Handle the return values of retain-count-related functions.
    887 //===----------------------------------------------------------------------===//
    888 
    889 bool RetainCountChecker::evalCall(const CallEvent &Call,
    890                                   CheckerContext &C) const {
    891   ProgramStateRef state = C.getState();
    892   const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
    893   if (!FD)
    894     return false;
    895 
    896   const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
    897   if (!CE)
    898     return false;
    899 
    900   RetainSummaryManager &SmrMgr = getSummaryManager(C);
    901   QualType ResultTy = Call.getResultType();
    902 
    903   // See if the function has 'rc_ownership_trusted_implementation'
    904   // annotate attribute. If it does, we will not inline it.
    905   bool hasTrustedImplementationAnnotation = false;
    906 
    907   const LocationContext *LCtx = C.getLocationContext();
    908 
    909   using BehaviorSummary = RetainSummaryManager::BehaviorSummary;
    910   Optional<BehaviorSummary> BSmr =
    911       SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation);
    912 
    913   // See if it's one of the specific functions we know how to eval.
    914   if (!BSmr)
    915     return false;
    916 
    917   // Bind the return value.
    918   if (BSmr == BehaviorSummary::Identity ||
    919       BSmr == BehaviorSummary::IdentityOrZero ||
    920       BSmr == BehaviorSummary::IdentityThis) {
    921 
    922     const Expr *BindReturnTo =
    923         (BSmr == BehaviorSummary::IdentityThis)
    924             ? cast<CXXMemberCallExpr>(CE)->getImplicitObjectArgument()
    925             : CE->getArg(0);
    926     SVal RetVal = state->getSVal(BindReturnTo, LCtx);
    927 
    928     // If the receiver is unknown or the function has
    929     // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
    930     // return value.
    931     // FIXME: this branch is very strange.
    932     if (RetVal.isUnknown() ||
    933         (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
    934       SValBuilder &SVB = C.getSValBuilder();
    935       RetVal =
    936           SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
    937     }
    938 
    939     // Bind the value.
    940     state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
    941 
    942     if (BSmr == BehaviorSummary::IdentityOrZero) {
    943       // Add a branch where the output is zero.
    944       ProgramStateRef NullOutputState = C.getState();
    945 
    946       // Assume that output is zero on the other branch.
    947       NullOutputState = NullOutputState->BindExpr(
    948           CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false);
    949       C.addTransition(NullOutputState, &getCastFailTag());
    950 
    951       // And on the original branch assume that both input and
    952       // output are non-zero.
    953       if (auto L = RetVal.getAs<DefinedOrUnknownSVal>())
    954         state = state->assume(*L, /*assumption=*/true);
    955 
    956     }
    957   }
    958 
    959   C.addTransition(state);
    960   return true;
    961 }
    962 
    963 ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
    964                                                  CheckerContext &C) const {
    965   ExplodedNode *Pred = C.getPredecessor();
    966 
    967   // Only adjust the reference count if this is the top-level call frame,
    968   // and not the result of inlining.  In the future, we should do
    969   // better checking even for inlined calls, and see if they match
    970   // with their expected semantics (e.g., the method should return a retained
    971   // object, etc.).
    972   if (!C.inTopFrame())
    973     return Pred;
    974 
    975   if (!S)
    976     return Pred;
    977 
    978   const Expr *RetE = S->getRetValue();
    979   if (!RetE)
    980     return Pred;
    981 
    982   ProgramStateRef state = C.getState();
    983   // We need to dig down to the symbolic base here because various
    984   // custom allocators do sometimes return the symbol with an offset.
    985   SymbolRef Sym = state->getSValAsScalarOrLoc(RetE, C.getLocationContext())
    986                       .getAsLocSymbol(/*IncludeBaseRegions=*/true);
    987   if (!Sym)
    988     return Pred;
    989 
    990   // Get the reference count binding (if any).
    991   const RefVal *T = getRefBinding(state, Sym);
    992   if (!T)
    993     return Pred;
    994 
    995   // Change the reference count.
    996   RefVal X = *T;
    997 
    998   switch (X.getKind()) {
    999     case RefVal::Owned: {
   1000       unsigned cnt = X.getCount();
   1001       assert(cnt > 0);
   1002       X.setCount(cnt - 1);
   1003       X = X ^ RefVal::ReturnedOwned;
   1004       break;
   1005     }
   1006 
   1007     case RefVal::NotOwned: {
   1008       unsigned cnt = X.getCount();
   1009       if (cnt) {
   1010         X.setCount(cnt - 1);
   1011         X = X ^ RefVal::ReturnedOwned;
   1012       } else {
   1013         X = X ^ RefVal::ReturnedNotOwned;
   1014       }
   1015       break;
   1016     }
   1017 
   1018     default:
   1019       return Pred;
   1020   }
   1021 
   1022   // Update the binding.
   1023   state = setRefBinding(state, Sym, X);
   1024   Pred = C.addTransition(state);
   1025 
   1026   // At this point we have updated the state properly.
   1027   // Everything after this is merely checking to see if the return value has
   1028   // been over- or under-retained.
   1029 
   1030   // Did we cache out?
   1031   if (!Pred)
   1032     return nullptr;
   1033 
   1034   // Update the autorelease counts.
   1035   static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
   1036   state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X, S);
   1037 
   1038   // Have we generated a sink node?
   1039   if (!state)
   1040     return nullptr;
   1041 
   1042   // Get the updated binding.
   1043   T = getRefBinding(state, Sym);
   1044   assert(T);
   1045   X = *T;
   1046 
   1047   // Consult the summary of the enclosing method.
   1048   RetainSummaryManager &Summaries = getSummaryManager(C);
   1049   const Decl *CD = &Pred->getCodeDecl();
   1050   RetEffect RE = RetEffect::MakeNoRet();
   1051 
   1052   // FIXME: What is the convention for blocks? Is there one?
   1053   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
   1054     const RetainSummary *Summ = Summaries.getSummary(AnyCall(MD));
   1055     RE = Summ->getRetEffect();
   1056   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
   1057     if (!isa<CXXMethodDecl>(FD)) {
   1058       const RetainSummary *Summ = Summaries.getSummary(AnyCall(FD));
   1059       RE = Summ->getRetEffect();
   1060     }
   1061   }
   1062 
   1063   return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
   1064 }
   1065 
   1066 ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
   1067                                                   CheckerContext &C,
   1068                                                   ExplodedNode *Pred,
   1069                                                   RetEffect RE, RefVal X,
   1070                                                   SymbolRef Sym,
   1071                                                   ProgramStateRef state) const {
   1072   // HACK: Ignore retain-count issues on values accessed through ivars,
   1073   // because of cases like this:
   1074   //   [_contentView retain];
   1075   //   [_contentView removeFromSuperview];
   1076   //   [self addSubview:_contentView]; // invalidates 'self'
   1077   //   [_contentView release];
   1078   if (X.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
   1079     return Pred;
   1080 
   1081   // Any leaks or other errors?
   1082   if (X.isReturnedOwned() && X.getCount() == 0) {
   1083     if (RE.getKind() != RetEffect::NoRet) {
   1084       if (!RE.isOwned()) {
   1085 
   1086         // The returning type is a CF, we expect the enclosing method should
   1087         // return ownership.
   1088         X = X ^ RefVal::ErrorLeakReturned;
   1089 
   1090         // Generate an error node.
   1091         state = setRefBinding(state, Sym, X);
   1092 
   1093         static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
   1094         ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
   1095         if (N) {
   1096           const LangOptions &LOpts = C.getASTContext().getLangOpts();
   1097           auto R =
   1098               std::make_unique<RefLeakReport>(*LeakAtReturn, LOpts, N, Sym, C);
   1099           C.emitReport(std::move(R));
   1100         }
   1101         return N;
   1102       }
   1103     }
   1104   } else if (X.isReturnedNotOwned()) {
   1105     if (RE.isOwned()) {
   1106       if (X.getIvarAccessHistory() ==
   1107             RefVal::IvarAccessHistory::AccessedDirectly) {
   1108         // Assume the method was trying to transfer a +1 reference from a
   1109         // strong ivar to the caller.
   1110         state = setRefBinding(state, Sym,
   1111                               X.releaseViaIvar() ^ RefVal::ReturnedOwned);
   1112       } else {
   1113         // Trying to return a not owned object to a caller expecting an
   1114         // owned object.
   1115         state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
   1116 
   1117         static CheckerProgramPointTag
   1118             ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
   1119 
   1120         ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
   1121         if (N) {
   1122           auto R = std::make_unique<RefCountReport>(
   1123               *ReturnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
   1124           C.emitReport(std::move(R));
   1125         }
   1126         return N;
   1127       }
   1128     }
   1129   }
   1130   return Pred;
   1131 }
   1132 
   1133 //===----------------------------------------------------------------------===//
   1134 // Check various ways a symbol can be invalidated.
   1135 //===----------------------------------------------------------------------===//
   1136 
   1137 void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
   1138                                    CheckerContext &C) const {
   1139   ProgramStateRef state = C.getState();
   1140   const MemRegion *MR = loc.getAsRegion();
   1141 
   1142   // Find all symbols referenced by 'val' that we are tracking
   1143   // and stop tracking them.
   1144   if (MR && shouldEscapeRegion(MR)) {
   1145     state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
   1146     C.addTransition(state);
   1147   }
   1148 }
   1149 
   1150 ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
   1151                                                SVal Cond,
   1152                                                bool Assumption) const {
   1153   // FIXME: We may add to the interface of evalAssume the list of symbols
   1154   //  whose assumptions have changed.  For now we just iterate through the
   1155   //  bindings and check if any of the tracked symbols are NULL.  This isn't
   1156   //  too bad since the number of symbols we will track in practice are
   1157   //  probably small and evalAssume is only called at branches and a few
   1158   //  other places.
   1159   RefBindingsTy B = state->get<RefBindings>();
   1160 
   1161   if (B.isEmpty())
   1162     return state;
   1163 
   1164   bool changed = false;
   1165   RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
   1166   ConstraintManager &CMgr = state->getConstraintManager();
   1167 
   1168   for (auto &I : B) {
   1169     // Check if the symbol is null stop tracking the symbol.
   1170     ConditionTruthVal AllocFailed = CMgr.isNull(state, I.first);
   1171     if (AllocFailed.isConstrainedTrue()) {
   1172       changed = true;
   1173       B = RefBFactory.remove(B, I.first);
   1174     }
   1175   }
   1176 
   1177   if (changed)
   1178     state = state->set<RefBindings>(B);
   1179 
   1180   return state;
   1181 }
   1182 
   1183 ProgramStateRef RetainCountChecker::checkRegionChanges(
   1184     ProgramStateRef state, const InvalidatedSymbols *invalidated,
   1185     ArrayRef<const MemRegion *> ExplicitRegions,
   1186     ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx,
   1187     const CallEvent *Call) const {
   1188   if (!invalidated)
   1189     return state;
   1190 
   1191   llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
   1192 
   1193   for (const MemRegion *I : ExplicitRegions)
   1194     if (const SymbolicRegion *SR = I->StripCasts()->getAs<SymbolicRegion>())
   1195       WhitelistedSymbols.insert(SR->getSymbol());
   1196 
   1197   for (SymbolRef sym : *invalidated) {
   1198     if (WhitelistedSymbols.count(sym))
   1199       continue;
   1200     // Remove any existing reference-count binding.
   1201     state = removeRefBinding(state, sym);
   1202   }
   1203   return state;
   1204 }
   1205 
   1206 ProgramStateRef
   1207 RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
   1208                                             ExplodedNode *Pred,
   1209                                             const ProgramPointTag *Tag,
   1210                                             CheckerContext &Ctx,
   1211                                             SymbolRef Sym,
   1212                                             RefVal V,
   1213                                             const ReturnStmt *S) const {
   1214   unsigned ACnt = V.getAutoreleaseCount();
   1215 
   1216   // No autorelease counts?  Nothing to be done.
   1217   if (!ACnt)
   1218     return state;
   1219 
   1220   unsigned Cnt = V.getCount();
   1221 
   1222   // FIXME: Handle sending 'autorelease' to already released object.
   1223 
   1224   if (V.getKind() == RefVal::ReturnedOwned)
   1225     ++Cnt;
   1226 
   1227   // If we would over-release here, but we know the value came from an ivar,
   1228   // assume it was a strong ivar that's just been relinquished.
   1229   if (ACnt > Cnt &&
   1230       V.getIvarAccessHistory() == RefVal::IvarAccessHistory::AccessedDirectly) {
   1231     V = V.releaseViaIvar();
   1232     --ACnt;
   1233   }
   1234 
   1235   if (ACnt <= Cnt) {
   1236     if (ACnt == Cnt) {
   1237       V.clearCounts();
   1238       if (V.getKind() == RefVal::ReturnedOwned) {
   1239         V = V ^ RefVal::ReturnedNotOwned;
   1240       } else {
   1241         V = V ^ RefVal::NotOwned;
   1242       }
   1243     } else {
   1244       V.setCount(V.getCount() - ACnt);
   1245       V.setAutoreleaseCount(0);
   1246     }
   1247     return setRefBinding(state, Sym, V);
   1248   }
   1249 
   1250   // HACK: Ignore retain-count issues on values accessed through ivars,
   1251   // because of cases like this:
   1252   //   [_contentView retain];
   1253   //   [_contentView removeFromSuperview];
   1254   //   [self addSubview:_contentView]; // invalidates 'self'
   1255   //   [_contentView release];
   1256   if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
   1257     return state;
   1258 
   1259   // Woah!  More autorelease counts then retain counts left.
   1260   // Emit hard error.
   1261   V = V ^ RefVal::ErrorOverAutorelease;
   1262   state = setRefBinding(state, Sym, V);
   1263 
   1264   ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
   1265   if (N) {
   1266     SmallString<128> sbuf;
   1267     llvm::raw_svector_ostream os(sbuf);
   1268     os << "Object was autoreleased ";
   1269     if (V.getAutoreleaseCount() > 1)
   1270       os << V.getAutoreleaseCount() << " times but the object ";
   1271     else
   1272       os << "but ";
   1273     os << "has a +" << V.getCount() << " retain count";
   1274 
   1275     const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
   1276     auto R = std::make_unique<RefCountReport>(*OverAutorelease, LOpts, N, Sym,
   1277                                               os.str());
   1278     Ctx.emitReport(std::move(R));
   1279   }
   1280 
   1281   return nullptr;
   1282 }
   1283 
   1284 ProgramStateRef
   1285 RetainCountChecker::handleSymbolDeath(ProgramStateRef state,
   1286                                       SymbolRef sid, RefVal V,
   1287                                     SmallVectorImpl<SymbolRef> &Leaked) const {
   1288   bool hasLeak;
   1289 
   1290   // HACK: Ignore retain-count issues on values accessed through ivars,
   1291   // because of cases like this:
   1292   //   [_contentView retain];
   1293   //   [_contentView removeFromSuperview];
   1294   //   [self addSubview:_contentView]; // invalidates 'self'
   1295   //   [_contentView release];
   1296   if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
   1297     hasLeak = false;
   1298   else if (V.isOwned())
   1299     hasLeak = true;
   1300   else if (V.isNotOwned() || V.isReturnedOwned())
   1301     hasLeak = (V.getCount() > 0);
   1302   else
   1303     hasLeak = false;
   1304 
   1305   if (!hasLeak)
   1306     return removeRefBinding(state, sid);
   1307 
   1308   Leaked.push_back(sid);
   1309   return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
   1310 }
   1311 
   1312 ExplodedNode *
   1313 RetainCountChecker::processLeaks(ProgramStateRef state,
   1314                                  SmallVectorImpl<SymbolRef> &Leaked,
   1315                                  CheckerContext &Ctx,
   1316                                  ExplodedNode *Pred) const {
   1317   // Generate an intermediate node representing the leak point.
   1318   ExplodedNode *N = Ctx.addTransition(state, Pred);
   1319   const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
   1320 
   1321   if (N) {
   1322     for (SymbolRef L : Leaked) {
   1323       const RefCountBug &BT = Pred ? *LeakWithinFunction : *LeakAtReturn;
   1324       Ctx.emitReport(std::make_unique<RefLeakReport>(BT, LOpts, N, L, Ctx));
   1325     }
   1326   }
   1327 
   1328   return N;
   1329 }
   1330 
   1331 void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
   1332   if (!Ctx.inTopFrame())
   1333     return;
   1334 
   1335   RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
   1336   const LocationContext *LCtx = Ctx.getLocationContext();
   1337   const Decl *D = LCtx->getDecl();
   1338   Optional<AnyCall> C = AnyCall::forDecl(D);
   1339 
   1340   if (!C || SmrMgr.isTrustedReferenceCountImplementation(D))
   1341     return;
   1342 
   1343   ProgramStateRef state = Ctx.getState();
   1344   const RetainSummary *FunctionSummary = SmrMgr.getSummary(*C);
   1345   ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
   1346 
   1347   for (unsigned idx = 0, e = C->param_size(); idx != e; ++idx) {
   1348     const ParmVarDecl *Param = C->parameters()[idx];
   1349     SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
   1350 
   1351     QualType Ty = Param->getType();
   1352     const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
   1353     if (AE) {
   1354       ObjKind K = AE->getObjKind();
   1355       if (K == ObjKind::Generalized || K == ObjKind::OS ||
   1356           (TrackNSCFStartParam && (K == ObjKind::ObjC || K == ObjKind::CF))) {
   1357         RefVal NewVal = AE->getKind() == DecRef ? RefVal::makeOwned(K, Ty)
   1358                                                 : RefVal::makeNotOwned(K, Ty);
   1359         state = setRefBinding(state, Sym, NewVal);
   1360       }
   1361     }
   1362   }
   1363 
   1364   Ctx.addTransition(state);
   1365 }
   1366 
   1367 void RetainCountChecker::checkEndFunction(const ReturnStmt *RS,
   1368                                           CheckerContext &Ctx) const {
   1369   ExplodedNode *Pred = processReturn(RS, Ctx);
   1370 
   1371   // Created state cached out.
   1372   if (!Pred) {
   1373     return;
   1374   }
   1375 
   1376   ProgramStateRef state = Pred->getState();
   1377   RefBindingsTy B = state->get<RefBindings>();
   1378 
   1379   // Don't process anything within synthesized bodies.
   1380   const LocationContext *LCtx = Pred->getLocationContext();
   1381   if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
   1382     assert(!LCtx->inTopFrame());
   1383     return;
   1384   }
   1385 
   1386   for (auto &I : B) {
   1387     state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
   1388                                     I.first, I.second);
   1389     if (!state)
   1390       return;
   1391   }
   1392 
   1393   // If the current LocationContext has a parent, don't check for leaks.
   1394   // We will do that later.
   1395   // FIXME: we should instead check for imbalances of the retain/releases,
   1396   // and suggest annotations.
   1397   if (LCtx->getParent())
   1398     return;
   1399 
   1400   B = state->get<RefBindings>();
   1401   SmallVector<SymbolRef, 10> Leaked;
   1402 
   1403   for (auto &I : B)
   1404     state = handleSymbolDeath(state, I.first, I.second, Leaked);
   1405 
   1406   processLeaks(state, Leaked, Ctx, Pred);
   1407 }
   1408 
   1409 void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
   1410                                           CheckerContext &C) const {
   1411   ExplodedNode *Pred = C.getPredecessor();
   1412 
   1413   ProgramStateRef state = C.getState();
   1414   SmallVector<SymbolRef, 10> Leaked;
   1415 
   1416   // Update counts from autorelease pools
   1417   for (const auto &I: state->get<RefBindings>()) {
   1418     SymbolRef Sym = I.first;
   1419     if (SymReaper.isDead(Sym)) {
   1420       static CheckerProgramPointTag Tag(this, "DeadSymbolAutorelease");
   1421       const RefVal &V = I.second;
   1422       state = handleAutoreleaseCounts(state, Pred, &Tag, C, Sym, V);
   1423       if (!state)
   1424         return;
   1425 
   1426       // Fetch the new reference count from the state, and use it to handle
   1427       // this symbol.
   1428       state = handleSymbolDeath(state, Sym, *getRefBinding(state, Sym), Leaked);
   1429     }
   1430   }
   1431 
   1432   if (Leaked.empty()) {
   1433     C.addTransition(state);
   1434     return;
   1435   }
   1436 
   1437   Pred = processLeaks(state, Leaked, C, Pred);
   1438 
   1439   // Did we cache out?
   1440   if (!Pred)
   1441     return;
   1442 
   1443   // Now generate a new node that nukes the old bindings.
   1444   // The only bindings left at this point are the leaked symbols.
   1445   RefBindingsTy::Factory &F = state->get_context<RefBindings>();
   1446   RefBindingsTy B = state->get<RefBindings>();
   1447 
   1448   for (SymbolRef L : Leaked)
   1449     B = F.remove(B, L);
   1450 
   1451   state = state->set<RefBindings>(B);
   1452   C.addTransition(state, Pred);
   1453 }
   1454 
   1455 void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
   1456                                     const char *NL, const char *Sep) const {
   1457 
   1458   RefBindingsTy B = State->get<RefBindings>();
   1459 
   1460   if (B.isEmpty())
   1461     return;
   1462 
   1463   Out << Sep << NL;
   1464 
   1465   for (auto &I : B) {
   1466     Out << I.first << " : ";
   1467     I.second.print(Out);
   1468     Out << NL;
   1469   }
   1470 }
   1471 
   1472 //===----------------------------------------------------------------------===//
   1473 // Checker registration.
   1474 //===----------------------------------------------------------------------===//
   1475 
   1476 std::unique_ptr<CheckerProgramPointTag> RetainCountChecker::DeallocSentTag;
   1477 std::unique_ptr<CheckerProgramPointTag> RetainCountChecker::CastFailTag;
   1478 
   1479 void ento::registerRetainCountBase(CheckerManager &Mgr) {
   1480   auto *Chk = Mgr.registerChecker<RetainCountChecker>();
   1481   Chk->DeallocSentTag =
   1482       std::make_unique<CheckerProgramPointTag>(Chk, "DeallocSent");
   1483   Chk->CastFailTag =
   1484       std::make_unique<CheckerProgramPointTag>(Chk, "DynamicCastFail");
   1485 }
   1486 
   1487 bool ento::shouldRegisterRetainCountBase(const CheckerManager &mgr) {
   1488   return true;
   1489 }
   1490 void ento::registerRetainCountChecker(CheckerManager &Mgr) {
   1491   auto *Chk = Mgr.getChecker<RetainCountChecker>();
   1492   Chk->TrackObjCAndCFObjects = true;
   1493   Chk->TrackNSCFStartParam = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
   1494       Mgr.getCurrentCheckerName(), "TrackNSCFStartParam");
   1495 
   1496 #define INIT_BUGTYPE(KIND)                                                     \
   1497   Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(),       \
   1498                                             RefCountBug::KIND);
   1499   // TODO: Ideally, we should have a checker for each of these bug types.
   1500   INIT_BUGTYPE(UseAfterRelease)
   1501   INIT_BUGTYPE(ReleaseNotOwned)
   1502   INIT_BUGTYPE(DeallocNotOwned)
   1503   INIT_BUGTYPE(FreeNotOwned)
   1504   INIT_BUGTYPE(OverAutorelease)
   1505   INIT_BUGTYPE(ReturnNotOwnedForOwned)
   1506   INIT_BUGTYPE(LeakWithinFunction)
   1507   INIT_BUGTYPE(LeakAtReturn)
   1508 #undef INIT_BUGTYPE
   1509 }
   1510 
   1511 bool ento::shouldRegisterRetainCountChecker(const CheckerManager &mgr) {
   1512   return true;
   1513 }
   1514 
   1515 void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
   1516   auto *Chk = Mgr.getChecker<RetainCountChecker>();
   1517   Chk->TrackOSObjects = true;
   1518 
   1519   // FIXME: We want bug reports to always have the same checker name associated
   1520   // with them, yet here, if RetainCountChecker is disabled but
   1521   // OSObjectRetainCountChecker is enabled, the checker names will be different.
   1522   // This hack will make it so that the checker name depends on which checker is
   1523   // enabled rather than on the registration order.
   1524   // For the most part, we want **non-hidden checkers** to be associated with
   1525   // diagnostics, and **hidden checker options** with the fine-tuning of
   1526   // modeling. Following this logic, OSObjectRetainCountChecker should be the
   1527   // latter, but we can't just remove it for backward compatibility reasons.
   1528 #define LAZY_INIT_BUGTYPE(KIND)                                                \
   1529   if (!Chk->KIND)                                                              \
   1530     Chk->KIND = std::make_unique<RefCountBug>(Mgr.getCurrentCheckerName(),     \
   1531                                               RefCountBug::KIND);
   1532   LAZY_INIT_BUGTYPE(UseAfterRelease)
   1533   LAZY_INIT_BUGTYPE(ReleaseNotOwned)
   1534   LAZY_INIT_BUGTYPE(DeallocNotOwned)
   1535   LAZY_INIT_BUGTYPE(FreeNotOwned)
   1536   LAZY_INIT_BUGTYPE(OverAutorelease)
   1537   LAZY_INIT_BUGTYPE(ReturnNotOwnedForOwned)
   1538   LAZY_INIT_BUGTYPE(LeakWithinFunction)
   1539   LAZY_INIT_BUGTYPE(LeakAtReturn)
   1540 #undef LAZY_INIT_BUGTYPE
   1541 }
   1542 
   1543 bool ento::shouldRegisterOSObjectRetainCountChecker(const CheckerManager &mgr) {
   1544   return true;
   1545 }
   1546