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