]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / lib / StaticAnalyzer / Checkers / RetainCountChecker / RetainCountChecker.cpp
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 bool shouldEscapeRegion(const MemRegion *R) {
533
534   // We do not currently model what happens when a symbol is
535   // assigned to a struct field, so be conservative here and let the symbol
536   // go. TODO: This could definitely be improved upon.
537   return !R->hasStackStorage() || !isa<VarRegion>(R);
538 }
539
540 static SmallVector<ProgramStateRef, 2>
541 updateOutParameters(ProgramStateRef State, const RetainSummary &Summ,
542                     const CallEvent &CE) {
543
544   SVal L = CE.getReturnValue();
545
546   // Splitting is required to support out parameters,
547   // as out parameters might be created only on the "success" branch.
548   // We want to avoid eagerly splitting unless out parameters are actually
549   // needed.
550   bool SplitNecessary = false;
551   for (auto &P : Summ.getArgEffects())
552     if (P.second.getKind() == RetainedOutParameterOnNonZero ||
553         P.second.getKind() == RetainedOutParameterOnZero)
554       SplitNecessary = true;
555
556   ProgramStateRef AssumeNonZeroReturn = State;
557   ProgramStateRef AssumeZeroReturn = State;
558
559   if (SplitNecessary) {
560     if (auto DL = L.getAs<DefinedOrUnknownSVal>()) {
561       AssumeNonZeroReturn = AssumeNonZeroReturn->assume(*DL, true);
562       AssumeZeroReturn = AssumeZeroReturn->assume(*DL, false);
563     }
564   }
565
566   for (unsigned idx = 0, e = CE.getNumArgs(); idx != e; ++idx) {
567     SVal ArgVal = CE.getArgSVal(idx);
568     ArgEffect AE = Summ.getArg(idx);
569
570     auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.getAsRegion());
571     if (!ArgRegion)
572       continue;
573
574     QualType PointeeTy = ArgRegion->getValueType();
575     SVal PointeeVal = State->getSVal(ArgRegion);
576     SymbolRef Pointee = PointeeVal.getAsLocSymbol();
577     if (!Pointee)
578       continue;
579
580     if (shouldEscapeRegion(ArgRegion))
581       continue;
582
583     auto makeNotOwnedParameter = [&](ProgramStateRef St) {
584       return setRefBinding(St, Pointee,
585                            RefVal::makeNotOwned(AE.getObjKind(), PointeeTy));
586     };
587     auto makeOwnedParameter = [&](ProgramStateRef St) {
588       return setRefBinding(St, Pointee,
589                            RefVal::makeOwned(ObjKind::OS, PointeeTy));
590     };
591
592     switch (AE.getKind()) {
593     case UnretainedOutParameter:
594       AssumeNonZeroReturn = makeNotOwnedParameter(AssumeNonZeroReturn);
595       AssumeZeroReturn = makeNotOwnedParameter(AssumeZeroReturn);
596       break;
597     case RetainedOutParameter:
598       AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
599       AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
600       break;
601     case RetainedOutParameterOnNonZero:
602       AssumeNonZeroReturn = makeOwnedParameter(AssumeNonZeroReturn);
603       break;
604     case RetainedOutParameterOnZero:
605       AssumeZeroReturn = makeOwnedParameter(AssumeZeroReturn);
606       break;
607     default:
608       break;
609     }
610   }
611
612   if (SplitNecessary) {
613     return {AssumeNonZeroReturn, AssumeZeroReturn};
614   } else {
615     assert(AssumeZeroReturn == AssumeNonZeroReturn);
616     return {AssumeZeroReturn};
617   }
618 }
619
620 void RetainCountChecker::checkSummary(const RetainSummary &Summ,
621                                       const CallEvent &CallOrMsg,
622                                       CheckerContext &C) const {
623   ProgramStateRef state = C.getState();
624
625   // Evaluate the effect of the arguments.
626   RefVal::Kind hasErr = (RefVal::Kind) 0;
627   SourceRange ErrorRange;
628   SymbolRef ErrorSym = nullptr;
629
630   // Helper tag for providing diagnostics: indicate whether dealloc was sent
631   // at this location.
632   static CheckerProgramPointTag DeallocSentTag(this, DeallocTagDescription);
633   bool DeallocSent = false;
634
635   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
636     SVal V = CallOrMsg.getArgSVal(idx);
637
638     ArgEffect Effect = Summ.getArg(idx);
639     if (SymbolRef Sym = V.getAsLocSymbol()) {
640       if (const RefVal *T = getRefBinding(state, Sym)) {
641
642         if (shouldEscapeOSArgumentOnCall(CallOrMsg, idx, T))
643           Effect = ArgEffect(StopTrackingHard, ObjKind::OS);
644
645         state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
646         if (hasErr) {
647           ErrorRange = CallOrMsg.getArgSourceRange(idx);
648           ErrorSym = Sym;
649           break;
650         } else if (Effect.getKind() == Dealloc) {
651           DeallocSent = true;
652         }
653       }
654     }
655   }
656
657   // Evaluate the effect on the message receiver / `this` argument.
658   bool ReceiverIsTracked = false;
659   if (!hasErr) {
660     if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
661       if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
662         if (const RefVal *T = getRefBinding(state, Sym)) {
663           ReceiverIsTracked = true;
664           state = updateSymbol(state, Sym, *T,
665                                Summ.getReceiverEffect(), hasErr, C);
666           if (hasErr) {
667             ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
668             ErrorSym = Sym;
669           } else if (Summ.getReceiverEffect().getKind() == Dealloc) {
670             DeallocSent = true;
671           }
672         }
673       }
674     } else if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
675       if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
676         if (const RefVal *T = getRefBinding(state, Sym)) {
677           state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
678                                hasErr, C);
679           if (hasErr) {
680             ErrorRange = MCall->getOriginExpr()->getSourceRange();
681             ErrorSym = Sym;
682           }
683         }
684       }
685     }
686   }
687
688   // Process any errors.
689   if (hasErr) {
690     processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C);
691     return;
692   }
693
694   // Consult the summary for the return value.
695   RetEffect RE = Summ.getRetEffect();
696
697   if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
698     if (ReceiverIsTracked)
699       RE = getSummaryManager(C).getObjAllocRetEffect();
700     else
701       RE = RetEffect::MakeNoRet();
702   }
703
704   if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
705     QualType ResultTy = CallOrMsg.getResultType();
706     if (RE.notOwned()) {
707       const Expr *Ex = CallOrMsg.getOriginExpr();
708       assert(Ex);
709       ResultTy = GetReturnType(Ex, C.getASTContext());
710     }
711     if (Optional<RefVal> updatedRefVal = refValFromRetEffect(RE, ResultTy))
712       state = setRefBinding(state, Sym, *updatedRefVal);
713   }
714
715   SmallVector<ProgramStateRef, 2> Out =
716       updateOutParameters(state, Summ, CallOrMsg);
717
718   for (ProgramStateRef St : Out) {
719     if (DeallocSent) {
720       C.addTransition(St, C.getPredecessor(), &DeallocSentTag);
721     } else {
722       C.addTransition(St);
723     }
724   }
725 }
726
727 ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
728                                                  SymbolRef sym, RefVal V,
729                                                  ArgEffect AE,
730                                                  RefVal::Kind &hasErr,
731                                                  CheckerContext &C) const {
732   bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
733   if (AE.getObjKind() == ObjKind::ObjC && IgnoreRetainMsg) {
734     switch (AE.getKind()) {
735     default:
736       break;
737     case IncRef:
738       AE = AE.withKind(DoNothing);
739       break;
740     case DecRef:
741       AE = AE.withKind(DoNothing);
742       break;
743     case DecRefAndStopTrackingHard:
744       AE = AE.withKind(StopTracking);
745       break;
746     }
747   }
748
749   // Handle all use-after-releases.
750   if (V.getKind() == RefVal::Released) {
751     V = V ^ RefVal::ErrorUseAfterRelease;
752     hasErr = V.getKind();
753     return setRefBinding(state, sym, V);
754   }
755
756   switch (AE.getKind()) {
757     case UnretainedOutParameter:
758     case RetainedOutParameter:
759     case RetainedOutParameterOnZero:
760     case RetainedOutParameterOnNonZero:
761       llvm_unreachable("Applies to pointer-to-pointer parameters, which should "
762                        "not have ref state.");
763
764     case Dealloc: // NB. we only need to add a note in a non-error case.
765       switch (V.getKind()) {
766         default:
767           llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
768         case RefVal::Owned:
769           // The object immediately transitions to the released state.
770           V = V ^ RefVal::Released;
771           V.clearCounts();
772           return setRefBinding(state, sym, V);
773         case RefVal::NotOwned:
774           V = V ^ RefVal::ErrorDeallocNotOwned;
775           hasErr = V.getKind();
776           break;
777       }
778       break;
779
780     case MayEscape:
781       if (V.getKind() == RefVal::Owned) {
782         V = V ^ RefVal::NotOwned;
783         break;
784       }
785
786       LLVM_FALLTHROUGH;
787
788     case DoNothing:
789       return state;
790
791     case Autorelease:
792       // Update the autorelease counts.
793       V = V.autorelease();
794       break;
795
796     case StopTracking:
797     case StopTrackingHard:
798       return removeRefBinding(state, sym);
799
800     case IncRef:
801       switch (V.getKind()) {
802         default:
803           llvm_unreachable("Invalid RefVal state for a retain.");
804         case RefVal::Owned:
805         case RefVal::NotOwned:
806           V = V + 1;
807           break;
808       }
809       break;
810
811     case DecRef:
812     case DecRefBridgedTransferred:
813     case DecRefAndStopTrackingHard:
814       switch (V.getKind()) {
815         default:
816           // case 'RefVal::Released' handled above.
817           llvm_unreachable("Invalid RefVal state for a release.");
818
819         case RefVal::Owned:
820           assert(V.getCount() > 0);
821           if (V.getCount() == 1) {
822             if (AE.getKind() == DecRefBridgedTransferred ||
823                 V.getIvarAccessHistory() ==
824                   RefVal::IvarAccessHistory::AccessedDirectly)
825               V = V ^ RefVal::NotOwned;
826             else
827               V = V ^ RefVal::Released;
828           } else if (AE.getKind() == DecRefAndStopTrackingHard) {
829             return removeRefBinding(state, sym);
830           }
831
832           V = V - 1;
833           break;
834
835         case RefVal::NotOwned:
836           if (V.getCount() > 0) {
837             if (AE.getKind() == DecRefAndStopTrackingHard)
838               return removeRefBinding(state, sym);
839             V = V - 1;
840           } else if (V.getIvarAccessHistory() ==
841                        RefVal::IvarAccessHistory::AccessedDirectly) {
842             // Assume that the instance variable was holding on the object at
843             // +1, and we just didn't know.
844             if (AE.getKind() == DecRefAndStopTrackingHard)
845               return removeRefBinding(state, sym);
846             V = V.releaseViaIvar() ^ RefVal::Released;
847           } else {
848             V = V ^ RefVal::ErrorReleaseNotOwned;
849             hasErr = V.getKind();
850           }
851           break;
852       }
853       break;
854   }
855   return setRefBinding(state, sym, V);
856 }
857
858 void RetainCountChecker::processNonLeakError(ProgramStateRef St,
859                                              SourceRange ErrorRange,
860                                              RefVal::Kind ErrorKind,
861                                              SymbolRef Sym,
862                                              CheckerContext &C) const {
863   // HACK: Ignore retain-count issues on values accessed through ivars,
864   // because of cases like this:
865   //   [_contentView retain];
866   //   [_contentView removeFromSuperview];
867   //   [self addSubview:_contentView]; // invalidates 'self'
868   //   [_contentView release];
869   if (const RefVal *RV = getRefBinding(St, Sym))
870     if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
871       return;
872
873   ExplodedNode *N = C.generateErrorNode(St);
874   if (!N)
875     return;
876
877   RefCountBug *BT;
878   switch (ErrorKind) {
879     default:
880       llvm_unreachable("Unhandled error.");
881     case RefVal::ErrorUseAfterRelease:
882       if (!useAfterRelease)
883         useAfterRelease.reset(new UseAfterRelease(this));
884       BT = useAfterRelease.get();
885       break;
886     case RefVal::ErrorReleaseNotOwned:
887       if (!releaseNotOwned)
888         releaseNotOwned.reset(new BadRelease(this));
889       BT = releaseNotOwned.get();
890       break;
891     case RefVal::ErrorDeallocNotOwned:
892       if (!deallocNotOwned)
893         deallocNotOwned.reset(new DeallocNotOwned(this));
894       BT = deallocNotOwned.get();
895       break;
896   }
897
898   assert(BT);
899   auto report = llvm::make_unique<RefCountReport>(
900       *BT, C.getASTContext().getLangOpts(), N, Sym);
901   report->addRange(ErrorRange);
902   C.emitReport(std::move(report));
903 }
904
905 //===----------------------------------------------------------------------===//
906 // Handle the return values of retain-count-related functions.
907 //===----------------------------------------------------------------------===//
908
909 bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
910   // Get the callee. We're only interested in simple C functions.
911   ProgramStateRef state = C.getState();
912   const FunctionDecl *FD = C.getCalleeDecl(CE);
913   if (!FD)
914     return false;
915
916   RetainSummaryManager &SmrMgr = getSummaryManager(C);
917   QualType ResultTy = CE->getCallReturnType(C.getASTContext());
918
919   // See if the function has 'rc_ownership_trusted_implementation'
920   // annotate attribute. If it does, we will not inline it.
921   bool hasTrustedImplementationAnnotation = false;
922
923   const LocationContext *LCtx = C.getLocationContext();
924
925   using BehaviorSummary = RetainSummaryManager::BehaviorSummary;
926   Optional<BehaviorSummary> BSmr =
927       SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation);
928
929   // See if it's one of the specific functions we know how to eval.
930   if (!BSmr)
931     return false;
932
933   // Bind the return value.
934   if (BSmr == BehaviorSummary::Identity ||
935       BSmr == BehaviorSummary::IdentityOrZero) {
936     SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
937
938     // If the receiver is unknown or the function has
939     // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
940     // return value.
941     if (RetVal.isUnknown() ||
942         (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
943       SValBuilder &SVB = C.getSValBuilder();
944       RetVal =
945           SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
946     }
947     state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
948
949     if (BSmr == BehaviorSummary::IdentityOrZero) {
950       // Add a branch where the output is zero.
951       ProgramStateRef NullOutputState = C.getState();
952
953       // Assume that output is zero on the other branch.
954       NullOutputState = NullOutputState->BindExpr(
955           CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false);
956
957       C.addTransition(NullOutputState);
958
959       // And on the original branch assume that both input and
960       // output are non-zero.
961       if (auto L = RetVal.getAs<DefinedOrUnknownSVal>())
962         state = state->assume(*L, /*Assumption=*/true);
963
964     }
965   }
966
967   C.addTransition(state);
968   return true;
969 }
970
971 ExplodedNode * RetainCountChecker::processReturn(const ReturnStmt *S,
972                                                  CheckerContext &C) const {
973   ExplodedNode *Pred = C.getPredecessor();
974
975   // Only adjust the reference count if this is the top-level call frame,
976   // and not the result of inlining.  In the future, we should do
977   // better checking even for inlined calls, and see if they match
978   // with their expected semantics (e.g., the method should return a retained
979   // object, etc.).
980   if (!C.inTopFrame())
981     return Pred;
982
983   if (!S)
984     return Pred;
985
986   const Expr *RetE = S->getRetValue();
987   if (!RetE)
988     return Pred;
989
990   ProgramStateRef state = C.getState();
991   SymbolRef Sym =
992     state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
993   if (!Sym)
994     return Pred;
995
996   // Get the reference count binding (if any).
997   const RefVal *T = getRefBinding(state, Sym);
998   if (!T)
999     return Pred;
1000
1001   // Change the reference count.
1002   RefVal X = *T;
1003
1004   switch (X.getKind()) {
1005     case RefVal::Owned: {
1006       unsigned cnt = X.getCount();
1007       assert(cnt > 0);
1008       X.setCount(cnt - 1);
1009       X = X ^ RefVal::ReturnedOwned;
1010       break;
1011     }
1012
1013     case RefVal::NotOwned: {
1014       unsigned cnt = X.getCount();
1015       if (cnt) {
1016         X.setCount(cnt - 1);
1017         X = X ^ RefVal::ReturnedOwned;
1018       } else {
1019         X = X ^ RefVal::ReturnedNotOwned;
1020       }
1021       break;
1022     }
1023
1024     default:
1025       return Pred;
1026   }
1027
1028   // Update the binding.
1029   state = setRefBinding(state, Sym, X);
1030   Pred = C.addTransition(state);
1031
1032   // At this point we have updated the state properly.
1033   // Everything after this is merely checking to see if the return value has
1034   // been over- or under-retained.
1035
1036   // Did we cache out?
1037   if (!Pred)
1038     return nullptr;
1039
1040   // Update the autorelease counts.
1041   static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
1042   state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X, S);
1043
1044   // Have we generated a sink node?
1045   if (!state)
1046     return nullptr;
1047
1048   // Get the updated binding.
1049   T = getRefBinding(state, Sym);
1050   assert(T);
1051   X = *T;
1052
1053   // Consult the summary of the enclosing method.
1054   RetainSummaryManager &Summaries = getSummaryManager(C);
1055   const Decl *CD = &Pred->getCodeDecl();
1056   RetEffect RE = RetEffect::MakeNoRet();
1057
1058   // FIXME: What is the convention for blocks? Is there one?
1059   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
1060     const RetainSummary *Summ = Summaries.getMethodSummary(MD);
1061     RE = Summ->getRetEffect();
1062   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
1063     if (!isa<CXXMethodDecl>(FD)) {
1064       const RetainSummary *Summ = Summaries.getFunctionSummary(FD);
1065       RE = Summ->getRetEffect();
1066     }
1067   }
1068
1069   return checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
1070 }
1071
1072 ExplodedNode * RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
1073                                                   CheckerContext &C,
1074                                                   ExplodedNode *Pred,
1075                                                   RetEffect RE, RefVal X,
1076                                                   SymbolRef Sym,
1077                                                   ProgramStateRef state) const {
1078   // HACK: Ignore retain-count issues on values accessed through ivars,
1079   // because of cases like this:
1080   //   [_contentView retain];
1081   //   [_contentView removeFromSuperview];
1082   //   [self addSubview:_contentView]; // invalidates 'self'
1083   //   [_contentView release];
1084   if (X.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1085     return Pred;
1086
1087   // Any leaks or other errors?
1088   if (X.isReturnedOwned() && X.getCount() == 0) {
1089     if (RE.getKind() != RetEffect::NoRet) {
1090       if (!RE.isOwned()) {
1091
1092         // The returning type is a CF, we expect the enclosing method should
1093         // return ownership.
1094         X = X ^ RefVal::ErrorLeakReturned;
1095
1096         // Generate an error node.
1097         state = setRefBinding(state, Sym, X);
1098
1099         static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
1100         ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
1101         if (N) {
1102           const LangOptions &LOpts = C.getASTContext().getLangOpts();
1103           auto R = llvm::make_unique<RefLeakReport>(
1104               *getLeakAtReturnBug(LOpts), LOpts, N, Sym, C);
1105           C.emitReport(std::move(R));
1106         }
1107         return N;
1108       }
1109     }
1110   } else if (X.isReturnedNotOwned()) {
1111     if (RE.isOwned()) {
1112       if (X.getIvarAccessHistory() ==
1113             RefVal::IvarAccessHistory::AccessedDirectly) {
1114         // Assume the method was trying to transfer a +1 reference from a
1115         // strong ivar to the caller.
1116         state = setRefBinding(state, Sym,
1117                               X.releaseViaIvar() ^ RefVal::ReturnedOwned);
1118       } else {
1119         // Trying to return a not owned object to a caller expecting an
1120         // owned object.
1121         state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
1122
1123         static CheckerProgramPointTag
1124             ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
1125
1126         ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
1127         if (N) {
1128           if (!returnNotOwnedForOwned)
1129             returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
1130
1131           auto R = llvm::make_unique<RefCountReport>(
1132               *returnNotOwnedForOwned, C.getASTContext().getLangOpts(), N, Sym);
1133           C.emitReport(std::move(R));
1134         }
1135         return N;
1136       }
1137     }
1138   }
1139   return Pred;
1140 }
1141
1142 //===----------------------------------------------------------------------===//
1143 // Check various ways a symbol can be invalidated.
1144 //===----------------------------------------------------------------------===//
1145
1146 void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
1147                                    CheckerContext &C) const {
1148   // Are we storing to something that causes the value to "escape"?
1149   bool escapes = true;
1150
1151   // A value escapes in three possible cases (this may change):
1152   //
1153   // (1) we are binding to something that is not a memory region.
1154   // (2) we are binding to a memregion that does not have stack storage
1155   ProgramStateRef state = C.getState();
1156
1157   if (auto regionLoc = loc.getAs<loc::MemRegionVal>()) {
1158     escapes = shouldEscapeRegion(regionLoc->getRegion());
1159   }
1160
1161   // If we are storing the value into an auto function scope variable annotated
1162   // with (__attribute__((cleanup))), stop tracking the value to avoid leak
1163   // false positives.
1164   if (const auto *LVR = dyn_cast_or_null<VarRegion>(loc.getAsRegion())) {
1165     const VarDecl *VD = LVR->getDecl();
1166     if (VD->hasAttr<CleanupAttr>()) {
1167       escapes = true;
1168     }
1169   }
1170
1171   // If our store can represent the binding and we aren't storing to something
1172   // that doesn't have local storage then just return and have the simulation
1173   // state continue as is.
1174   if (!escapes)
1175       return;
1176
1177   // Otherwise, find all symbols referenced by 'val' that we are tracking
1178   // and stop tracking them.
1179   state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
1180   C.addTransition(state);
1181 }
1182
1183 ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
1184                                                SVal Cond,
1185                                                bool Assumption) const {
1186   // FIXME: We may add to the interface of evalAssume the list of symbols
1187   //  whose assumptions have changed.  For now we just iterate through the
1188   //  bindings and check if any of the tracked symbols are NULL.  This isn't
1189   //  too bad since the number of symbols we will track in practice are
1190   //  probably small and evalAssume is only called at branches and a few
1191   //  other places.
1192   RefBindingsTy B = state->get<RefBindings>();
1193
1194   if (B.isEmpty())
1195     return state;
1196
1197   bool changed = false;
1198   RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
1199
1200   for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1201     // Check if the symbol is null stop tracking the symbol.
1202     ConstraintManager &CMgr = state->getConstraintManager();
1203     ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
1204     if (AllocFailed.isConstrainedTrue()) {
1205       changed = true;
1206       B = RefBFactory.remove(B, I.getKey());
1207     }
1208   }
1209
1210   if (changed)
1211     state = state->set<RefBindings>(B);
1212
1213   return state;
1214 }
1215
1216 ProgramStateRef
1217 RetainCountChecker::checkRegionChanges(ProgramStateRef state,
1218                                        const InvalidatedSymbols *invalidated,
1219                                        ArrayRef<const MemRegion *> ExplicitRegions,
1220                                        ArrayRef<const MemRegion *> Regions,
1221                                        const LocationContext *LCtx,
1222                                        const CallEvent *Call) const {
1223   if (!invalidated)
1224     return state;
1225
1226   llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
1227   for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
1228        E = ExplicitRegions.end(); I != E; ++I) {
1229     if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>())
1230       WhitelistedSymbols.insert(SR->getSymbol());
1231   }
1232
1233   for (SymbolRef sym :
1234        llvm::make_range(invalidated->begin(), invalidated->end())) {
1235     if (WhitelistedSymbols.count(sym))
1236       continue;
1237     // Remove any existing reference-count binding.
1238     state = removeRefBinding(state, sym);
1239   }
1240   return state;
1241 }
1242
1243 ProgramStateRef
1244 RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
1245                                             ExplodedNode *Pred,
1246                                             const ProgramPointTag *Tag,
1247                                             CheckerContext &Ctx,
1248                                             SymbolRef Sym,
1249                                             RefVal V,
1250                                             const ReturnStmt *S) const {
1251   unsigned ACnt = V.getAutoreleaseCount();
1252
1253   // No autorelease counts?  Nothing to be done.
1254   if (!ACnt)
1255     return state;
1256
1257   unsigned Cnt = V.getCount();
1258
1259   // FIXME: Handle sending 'autorelease' to already released object.
1260
1261   if (V.getKind() == RefVal::ReturnedOwned)
1262     ++Cnt;
1263
1264   // If we would over-release here, but we know the value came from an ivar,
1265   // assume it was a strong ivar that's just been relinquished.
1266   if (ACnt > Cnt &&
1267       V.getIvarAccessHistory() == RefVal::IvarAccessHistory::AccessedDirectly) {
1268     V = V.releaseViaIvar();
1269     --ACnt;
1270   }
1271
1272   if (ACnt <= Cnt) {
1273     if (ACnt == Cnt) {
1274       V.clearCounts();
1275       if (V.getKind() == RefVal::ReturnedOwned) {
1276         V = V ^ RefVal::ReturnedNotOwned;
1277       } else {
1278         V = V ^ RefVal::NotOwned;
1279       }
1280     } else {
1281       V.setCount(V.getCount() - ACnt);
1282       V.setAutoreleaseCount(0);
1283     }
1284     return setRefBinding(state, Sym, V);
1285   }
1286
1287   // HACK: Ignore retain-count issues on values accessed through ivars,
1288   // because of cases like this:
1289   //   [_contentView retain];
1290   //   [_contentView removeFromSuperview];
1291   //   [self addSubview:_contentView]; // invalidates 'self'
1292   //   [_contentView release];
1293   if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1294     return state;
1295
1296   // Woah!  More autorelease counts then retain counts left.
1297   // Emit hard error.
1298   V = V ^ RefVal::ErrorOverAutorelease;
1299   state = setRefBinding(state, Sym, V);
1300
1301   ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
1302   if (N) {
1303     SmallString<128> sbuf;
1304     llvm::raw_svector_ostream os(sbuf);
1305     os << "Object was autoreleased ";
1306     if (V.getAutoreleaseCount() > 1)
1307       os << V.getAutoreleaseCount() << " times but the object ";
1308     else
1309       os << "but ";
1310     os << "has a +" << V.getCount() << " retain count";
1311
1312     if (!overAutorelease)
1313       overAutorelease.reset(new OverAutorelease(this));
1314
1315     const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1316     auto R = llvm::make_unique<RefCountReport>(*overAutorelease, LOpts, N, Sym,
1317                                             os.str());
1318     Ctx.emitReport(std::move(R));
1319   }
1320
1321   return nullptr;
1322 }
1323
1324 ProgramStateRef
1325 RetainCountChecker::handleSymbolDeath(ProgramStateRef state,
1326                                       SymbolRef sid, RefVal V,
1327                                     SmallVectorImpl<SymbolRef> &Leaked) const {
1328   bool hasLeak;
1329
1330   // HACK: Ignore retain-count issues on values accessed through ivars,
1331   // because of cases like this:
1332   //   [_contentView retain];
1333   //   [_contentView removeFromSuperview];
1334   //   [self addSubview:_contentView]; // invalidates 'self'
1335   //   [_contentView release];
1336   if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
1337     hasLeak = false;
1338   else if (V.isOwned())
1339     hasLeak = true;
1340   else if (V.isNotOwned() || V.isReturnedOwned())
1341     hasLeak = (V.getCount() > 0);
1342   else
1343     hasLeak = false;
1344
1345   if (!hasLeak)
1346     return removeRefBinding(state, sid);
1347
1348   Leaked.push_back(sid);
1349   return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
1350 }
1351
1352 ExplodedNode *
1353 RetainCountChecker::processLeaks(ProgramStateRef state,
1354                                  SmallVectorImpl<SymbolRef> &Leaked,
1355                                  CheckerContext &Ctx,
1356                                  ExplodedNode *Pred) const {
1357   // Generate an intermediate node representing the leak point.
1358   ExplodedNode *N = Ctx.addTransition(state, Pred);
1359
1360   if (N) {
1361     for (SmallVectorImpl<SymbolRef>::iterator
1362          I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
1363
1364       const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
1365       RefCountBug *BT = Pred ? getLeakWithinFunctionBug(LOpts)
1366                           : getLeakAtReturnBug(LOpts);
1367       assert(BT && "BugType not initialized.");
1368
1369       Ctx.emitReport(
1370           llvm::make_unique<RefLeakReport>(*BT, LOpts, N, *I, Ctx));
1371     }
1372   }
1373
1374   return N;
1375 }
1376
1377 static bool isISLObjectRef(QualType Ty) {
1378   return StringRef(Ty.getAsString()).startswith("isl_");
1379 }
1380
1381 void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
1382   if (!Ctx.inTopFrame())
1383     return;
1384
1385   RetainSummaryManager &SmrMgr = getSummaryManager(Ctx);
1386   const LocationContext *LCtx = Ctx.getLocationContext();
1387   const FunctionDecl *FD = dyn_cast<FunctionDecl>(LCtx->getDecl());
1388
1389   if (!FD || SmrMgr.isTrustedReferenceCountImplementation(FD))
1390     return;
1391
1392   ProgramStateRef state = Ctx.getState();
1393   const RetainSummary *FunctionSummary = SmrMgr.getFunctionSummary(FD);
1394   ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
1395
1396   for (unsigned idx = 0, e = FD->getNumParams(); idx != e; ++idx) {
1397     const ParmVarDecl *Param = FD->getParamDecl(idx);
1398     SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
1399
1400     QualType Ty = Param->getType();
1401     const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
1402     if (AE && AE->getKind() == DecRef && isISLObjectRef(Ty)) {
1403       state = setRefBinding(
1404           state, Sym, RefVal::makeOwned(ObjKind::Generalized, Ty));
1405     } else if (isISLObjectRef(Ty)) {
1406       state = setRefBinding(
1407           state, Sym,
1408           RefVal::makeNotOwned(ObjKind::Generalized, Ty));
1409     }
1410   }
1411
1412   Ctx.addTransition(state);
1413 }
1414
1415 void RetainCountChecker::checkEndFunction(const ReturnStmt *RS,
1416                                           CheckerContext &Ctx) const {
1417   ExplodedNode *Pred = processReturn(RS, Ctx);
1418
1419   // Created state cached out.
1420   if (!Pred) {
1421     return;
1422   }
1423
1424   ProgramStateRef state = Pred->getState();
1425   RefBindingsTy B = state->get<RefBindings>();
1426
1427   // Don't process anything within synthesized bodies.
1428   const LocationContext *LCtx = Pred->getLocationContext();
1429   if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
1430     assert(!LCtx->inTopFrame());
1431     return;
1432   }
1433
1434   for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1435     state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
1436                                     I->first, I->second);
1437     if (!state)
1438       return;
1439   }
1440
1441   // If the current LocationContext has a parent, don't check for leaks.
1442   // We will do that later.
1443   // FIXME: we should instead check for imbalances of the retain/releases,
1444   // and suggest annotations.
1445   if (LCtx->getParent())
1446     return;
1447
1448   B = state->get<RefBindings>();
1449   SmallVector<SymbolRef, 10> Leaked;
1450
1451   for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
1452     state = handleSymbolDeath(state, I->first, I->second, Leaked);
1453
1454   processLeaks(state, Leaked, Ctx, Pred);
1455 }
1456
1457 void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
1458                                           CheckerContext &C) const {
1459   ExplodedNode *Pred = C.getPredecessor();
1460
1461   ProgramStateRef state = C.getState();
1462   RefBindingsTy B = state->get<RefBindings>();
1463   SmallVector<SymbolRef, 10> Leaked;
1464
1465   // Update counts from autorelease pools
1466   for (const auto &I: state->get<RefBindings>()) {
1467     SymbolRef Sym = I.first;
1468     if (SymReaper.isDead(Sym)) {
1469       static CheckerProgramPointTag Tag(this, "DeadSymbolAutorelease");
1470       const RefVal &V = I.second;
1471       state = handleAutoreleaseCounts(state, Pred, &Tag, C, Sym, V);
1472       if (!state)
1473         return;
1474
1475       // Fetch the new reference count from the state, and use it to handle
1476       // this symbol.
1477       state = handleSymbolDeath(state, Sym, *getRefBinding(state, Sym), Leaked);
1478     }
1479   }
1480
1481   if (Leaked.empty()) {
1482     C.addTransition(state);
1483     return;
1484   }
1485
1486   Pred = processLeaks(state, Leaked, C, Pred);
1487
1488   // Did we cache out?
1489   if (!Pred)
1490     return;
1491
1492   // Now generate a new node that nukes the old bindings.
1493   // The only bindings left at this point are the leaked symbols.
1494   RefBindingsTy::Factory &F = state->get_context<RefBindings>();
1495   B = state->get<RefBindings>();
1496
1497   for (SmallVectorImpl<SymbolRef>::iterator I = Leaked.begin(),
1498                                             E = Leaked.end();
1499        I != E; ++I)
1500     B = F.remove(B, *I);
1501
1502   state = state->set<RefBindings>(B);
1503   C.addTransition(state, Pred);
1504 }
1505
1506 void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
1507                                     const char *NL, const char *Sep) const {
1508
1509   RefBindingsTy B = State->get<RefBindings>();
1510
1511   if (B.isEmpty())
1512     return;
1513
1514   Out << Sep << NL;
1515
1516   for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
1517     Out << I->first << " : ";
1518     I->second.print(Out);
1519     Out << NL;
1520   }
1521 }
1522
1523 //===----------------------------------------------------------------------===//
1524 // Checker registration.
1525 //===----------------------------------------------------------------------===//
1526
1527 void ento::registerRetainCountChecker(CheckerManager &Mgr) {
1528   auto *Chk = Mgr.registerChecker<RetainCountChecker>();
1529   Chk->TrackObjCAndCFObjects = true;
1530 }
1531
1532 // FIXME: remove this, hack for backwards compatibility:
1533 // it should be possible to enable the NS/CF retain count checker as
1534 // osx.cocoa.RetainCount, and it should be possible to disable
1535 // osx.OSObjectRetainCount using osx.cocoa.RetainCount:CheckOSObject=false.
1536 static bool hasPrevCheckOSObjectOptionDisabled(AnalyzerOptions &Options) {
1537   auto I = Options.Config.find("osx.cocoa.RetainCount:CheckOSObject");
1538   if (I != Options.Config.end())
1539     return I->getValue() == "false";
1540   return false;
1541 }
1542
1543 void ento::registerOSObjectRetainCountChecker(CheckerManager &Mgr) {
1544   auto *Chk = Mgr.registerChecker<RetainCountChecker>();
1545   if (!hasPrevCheckOSObjectOptionDisabled(Mgr.getAnalyzerOptions()))
1546     Chk->TrackOSObjects = true;
1547 }