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