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 "ClangSACheckers.h"
16 #include "AllocationDiagnostics.h"
17 #include "SelectorExtras.h"
18 #include "clang/AST/Attr.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "clang/AST/ParentMap.h"
22 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
23 #include "clang/Basic/LangOptions.h"
24 #include "clang/Basic/SourceManager.h"
25 #include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h"
26 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
27 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
28 #include "clang/StaticAnalyzer/Core/Checker.h"
29 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
30 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
31 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
32 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
33 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
34 #include "llvm/ADT/DenseMap.h"
35 #include "llvm/ADT/FoldingSet.h"
36 #include "llvm/ADT/ImmutableList.h"
37 #include "llvm/ADT/ImmutableMap.h"
38 #include "llvm/ADT/STLExtras.h"
39 #include "llvm/ADT/SmallString.h"
40 #include "llvm/ADT/StringExtras.h"
41 #include <cstdarg>
42 
43 using namespace clang;
44 using namespace ento;
45 using namespace objc_retain;
46 using llvm::StrInStrNoCase;
47 
48 //===----------------------------------------------------------------------===//
49 // Adapters for FoldingSet.
50 //===----------------------------------------------------------------------===//
51 
52 namespace llvm {
53 template <> struct FoldingSetTrait<ArgEffect> {
Profilellvm::FoldingSetTrait54 static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
55   ID.AddInteger((unsigned) X);
56 }
57 };
58 template <> struct FoldingSetTrait<RetEffect> {
Profilellvm::FoldingSetTrait59   static inline void Profile(const RetEffect &X, FoldingSetNodeID &ID) {
60     ID.AddInteger((unsigned) X.getKind());
61     ID.AddInteger((unsigned) X.getObjKind());
62 }
63 };
64 } // end llvm namespace
65 
66 //===----------------------------------------------------------------------===//
67 // Reference-counting logic (typestate + counts).
68 //===----------------------------------------------------------------------===//
69 
70 /// ArgEffects summarizes the effects of a function/method call on all of
71 /// its arguments.
72 typedef llvm::ImmutableMap<unsigned,ArgEffect> ArgEffects;
73 
74 namespace {
75 class RefVal {
76 public:
77   enum Kind {
78     Owned = 0, // Owning reference.
79     NotOwned,  // Reference is not owned by still valid (not freed).
80     Released,  // Object has been released.
81     ReturnedOwned, // Returned object passes ownership to caller.
82     ReturnedNotOwned, // Return object does not pass ownership to caller.
83     ERROR_START,
84     ErrorDeallocNotOwned, // -dealloc called on non-owned object.
85     ErrorDeallocGC, // Calling -dealloc with GC enabled.
86     ErrorUseAfterRelease, // Object used after released.
87     ErrorReleaseNotOwned, // Release of an object that was not owned.
88     ERROR_LEAK_START,
89     ErrorLeak,  // A memory leak due to excessive reference counts.
90     ErrorLeakReturned, // A memory leak due to the returning method not having
91                        // the correct naming conventions.
92     ErrorGCLeakReturned,
93     ErrorOverAutorelease,
94     ErrorReturnedNotOwned
95   };
96 
97   /// Tracks how an object referenced by an ivar has been used.
98   ///
99   /// This accounts for us not knowing if an arbitrary ivar is supposed to be
100   /// stored at +0 or +1.
101   enum class IvarAccessHistory {
102     None,
103     AccessedDirectly,
104     ReleasedAfterDirectAccess
105   };
106 
107 private:
108   /// The number of outstanding retains.
109   unsigned Cnt;
110   /// The number of outstanding autoreleases.
111   unsigned ACnt;
112   /// The (static) type of the object at the time we started tracking it.
113   QualType T;
114 
115   /// The current state of the object.
116   ///
117   /// See the RefVal::Kind enum for possible values.
118   unsigned RawKind : 5;
119 
120   /// The kind of object being tracked (CF or ObjC), if known.
121   ///
122   /// See the RetEffect::ObjKind enum for possible values.
123   unsigned RawObjectKind : 2;
124 
125   /// True if the current state and/or retain count may turn out to not be the
126   /// best possible approximation of the reference counting state.
127   ///
128   /// If true, the checker may decide to throw away ("override") this state
129   /// in favor of something else when it sees the object being used in new ways.
130   ///
131   /// This setting should not be propagated to state derived from this state.
132   /// Once we start deriving new states, it would be inconsistent to override
133   /// them.
134   unsigned RawIvarAccessHistory : 2;
135 
RefVal(Kind k,RetEffect::ObjKind o,unsigned cnt,unsigned acnt,QualType t,IvarAccessHistory IvarAccess)136   RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t,
137          IvarAccessHistory IvarAccess)
138     : Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast<unsigned>(k)),
139       RawObjectKind(static_cast<unsigned>(o)),
140       RawIvarAccessHistory(static_cast<unsigned>(IvarAccess)) {
141     assert(getKind() == k && "not enough bits for the kind");
142     assert(getObjKind() == o && "not enough bits for the object kind");
143     assert(getIvarAccessHistory() == IvarAccess && "not enough bits");
144   }
145 
146 public:
getKind() const147   Kind getKind() const { return static_cast<Kind>(RawKind); }
148 
getObjKind() const149   RetEffect::ObjKind getObjKind() const {
150     return static_cast<RetEffect::ObjKind>(RawObjectKind);
151   }
152 
getCount() const153   unsigned getCount() const { return Cnt; }
getAutoreleaseCount() const154   unsigned getAutoreleaseCount() const { return ACnt; }
getCombinedCounts() const155   unsigned getCombinedCounts() const { return Cnt + ACnt; }
clearCounts()156   void clearCounts() {
157     Cnt = 0;
158     ACnt = 0;
159   }
setCount(unsigned i)160   void setCount(unsigned i) {
161     Cnt = i;
162   }
setAutoreleaseCount(unsigned i)163   void setAutoreleaseCount(unsigned i) {
164     ACnt = i;
165   }
166 
getType() const167   QualType getType() const { return T; }
168 
169   /// Returns what the analyzer knows about direct accesses to a particular
170   /// instance variable.
171   ///
172   /// If the object with this refcount wasn't originally from an Objective-C
173   /// ivar region, this should always return IvarAccessHistory::None.
getIvarAccessHistory() const174   IvarAccessHistory getIvarAccessHistory() const {
175     return static_cast<IvarAccessHistory>(RawIvarAccessHistory);
176   }
177 
isOwned() const178   bool isOwned() const {
179     return getKind() == Owned;
180   }
181 
isNotOwned() const182   bool isNotOwned() const {
183     return getKind() == NotOwned;
184   }
185 
isReturnedOwned() const186   bool isReturnedOwned() const {
187     return getKind() == ReturnedOwned;
188   }
189 
isReturnedNotOwned() const190   bool isReturnedNotOwned() const {
191     return getKind() == ReturnedNotOwned;
192   }
193 
194   /// Create a state for an object whose lifetime is the responsibility of the
195   /// current function, at least partially.
196   ///
197   /// Most commonly, this is an owned object with a retain count of +1.
makeOwned(RetEffect::ObjKind o,QualType t,unsigned Count=1)198   static RefVal makeOwned(RetEffect::ObjKind o, QualType t,
199                           unsigned Count = 1) {
200     return RefVal(Owned, o, Count, 0, t, IvarAccessHistory::None);
201   }
202 
203   /// Create a state for an object whose lifetime is not the responsibility of
204   /// the current function.
205   ///
206   /// Most commonly, this is an unowned object with a retain count of +0.
makeNotOwned(RetEffect::ObjKind o,QualType t,unsigned Count=0)207   static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t,
208                              unsigned Count = 0) {
209     return RefVal(NotOwned, o, Count, 0, t, IvarAccessHistory::None);
210   }
211 
operator -(size_t i) const212   RefVal operator-(size_t i) const {
213     return RefVal(getKind(), getObjKind(), getCount() - i,
214                   getAutoreleaseCount(), getType(), getIvarAccessHistory());
215   }
216 
operator +(size_t i) const217   RefVal operator+(size_t i) const {
218     return RefVal(getKind(), getObjKind(), getCount() + i,
219                   getAutoreleaseCount(), getType(), getIvarAccessHistory());
220   }
221 
operator ^(Kind k) const222   RefVal operator^(Kind k) const {
223     return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(),
224                   getType(), getIvarAccessHistory());
225   }
226 
autorelease() const227   RefVal autorelease() const {
228     return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1,
229                   getType(), getIvarAccessHistory());
230   }
231 
withIvarAccess() const232   RefVal withIvarAccess() const {
233     assert(getIvarAccessHistory() == IvarAccessHistory::None);
234     return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(),
235                   getType(), IvarAccessHistory::AccessedDirectly);
236   }
releaseViaIvar() const237   RefVal releaseViaIvar() const {
238     assert(getIvarAccessHistory() == IvarAccessHistory::AccessedDirectly);
239     return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount(),
240                   getType(), IvarAccessHistory::ReleasedAfterDirectAccess);
241   }
242 
243   // Comparison, profiling, and pretty-printing.
244 
hasSameState(const RefVal & X) const245   bool hasSameState(const RefVal &X) const {
246     return getKind() == X.getKind() && Cnt == X.Cnt && ACnt == X.ACnt &&
247            getIvarAccessHistory() == X.getIvarAccessHistory();
248   }
249 
operator ==(const RefVal & X) const250   bool operator==(const RefVal& X) const {
251     return T == X.T && hasSameState(X) && getObjKind() == X.getObjKind();
252   }
253 
Profile(llvm::FoldingSetNodeID & ID) const254   void Profile(llvm::FoldingSetNodeID& ID) const {
255     ID.Add(T);
256     ID.AddInteger(RawKind);
257     ID.AddInteger(Cnt);
258     ID.AddInteger(ACnt);
259     ID.AddInteger(RawObjectKind);
260     ID.AddInteger(RawIvarAccessHistory);
261   }
262 
263   void print(raw_ostream &Out) const;
264 };
265 
print(raw_ostream & Out) const266 void RefVal::print(raw_ostream &Out) const {
267   if (!T.isNull())
268     Out << "Tracked " << T.getAsString() << '/';
269 
270   switch (getKind()) {
271     default: llvm_unreachable("Invalid RefVal kind");
272     case Owned: {
273       Out << "Owned";
274       unsigned cnt = getCount();
275       if (cnt) Out << " (+ " << cnt << ")";
276       break;
277     }
278 
279     case NotOwned: {
280       Out << "NotOwned";
281       unsigned cnt = getCount();
282       if (cnt) Out << " (+ " << cnt << ")";
283       break;
284     }
285 
286     case ReturnedOwned: {
287       Out << "ReturnedOwned";
288       unsigned cnt = getCount();
289       if (cnt) Out << " (+ " << cnt << ")";
290       break;
291     }
292 
293     case ReturnedNotOwned: {
294       Out << "ReturnedNotOwned";
295       unsigned cnt = getCount();
296       if (cnt) Out << " (+ " << cnt << ")";
297       break;
298     }
299 
300     case Released:
301       Out << "Released";
302       break;
303 
304     case ErrorDeallocGC:
305       Out << "-dealloc (GC)";
306       break;
307 
308     case ErrorDeallocNotOwned:
309       Out << "-dealloc (not-owned)";
310       break;
311 
312     case ErrorLeak:
313       Out << "Leaked";
314       break;
315 
316     case ErrorLeakReturned:
317       Out << "Leaked (Bad naming)";
318       break;
319 
320     case ErrorGCLeakReturned:
321       Out << "Leaked (GC-ed at return)";
322       break;
323 
324     case ErrorUseAfterRelease:
325       Out << "Use-After-Release [ERROR]";
326       break;
327 
328     case ErrorReleaseNotOwned:
329       Out << "Release of Not-Owned [ERROR]";
330       break;
331 
332     case RefVal::ErrorOverAutorelease:
333       Out << "Over-autoreleased";
334       break;
335 
336     case RefVal::ErrorReturnedNotOwned:
337       Out << "Non-owned object returned instead of owned";
338       break;
339   }
340 
341   switch (getIvarAccessHistory()) {
342   case IvarAccessHistory::None:
343     break;
344   case IvarAccessHistory::AccessedDirectly:
345     Out << " [direct ivar access]";
346     break;
347   case IvarAccessHistory::ReleasedAfterDirectAccess:
348     Out << " [released after direct ivar access]";
349   }
350 
351   if (ACnt) {
352     Out << " [autorelease -" << ACnt << ']';
353   }
354 }
355 } //end anonymous namespace
356 
357 //===----------------------------------------------------------------------===//
358 // RefBindings - State used to track object reference counts.
359 //===----------------------------------------------------------------------===//
360 
REGISTER_MAP_WITH_PROGRAMSTATE(RefBindings,SymbolRef,RefVal) const361 REGISTER_MAP_WITH_PROGRAMSTATE(RefBindings, SymbolRef, RefVal)
362 
363 static inline const RefVal *getRefBinding(ProgramStateRef State,
364                                           SymbolRef Sym) {
365   return State->get<RefBindings>(Sym);
366 }
367 
setRefBinding(ProgramStateRef State,SymbolRef Sym,RefVal Val)368 static inline ProgramStateRef setRefBinding(ProgramStateRef State,
369                                             SymbolRef Sym, RefVal Val) {
370   return State->set<RefBindings>(Sym, Val);
371 }
372 
removeRefBinding(ProgramStateRef State,SymbolRef Sym)373 static ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
374   return State->remove<RefBindings>(Sym);
375 }
376 
377 //===----------------------------------------------------------------------===//
378 // Function/Method behavior summaries.
379 //===----------------------------------------------------------------------===//
380 
381 namespace {
382 class RetainSummary {
383   /// Args - a map of (index, ArgEffect) pairs, where index
384   ///  specifies the argument (starting from 0).  This can be sparsely
385   ///  populated; arguments with no entry in Args use 'DefaultArgEffect'.
386   ArgEffects Args;
387 
388   /// DefaultArgEffect - The default ArgEffect to apply to arguments that
389   ///  do not have an entry in Args.
390   ArgEffect DefaultArgEffect;
391 
392   /// Receiver - If this summary applies to an Objective-C message expression,
393   ///  this is the effect applied to the state of the receiver.
394   ArgEffect Receiver;
395 
396   /// Ret - The effect on the return value.  Used to indicate if the
397   ///  function/method call returns a new tracked symbol.
398   RetEffect Ret;
399 
400 public:
RetainSummary(ArgEffects A,RetEffect R,ArgEffect defaultEff,ArgEffect ReceiverEff)401   RetainSummary(ArgEffects A, RetEffect R, ArgEffect defaultEff,
402                 ArgEffect ReceiverEff)
403     : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R) {}
404 
405   /// getArg - Return the argument effect on the argument specified by
406   ///  idx (starting from 0).
getArg(unsigned idx) const407   ArgEffect getArg(unsigned idx) const {
408     if (const ArgEffect *AE = Args.lookup(idx))
409       return *AE;
410 
411     return DefaultArgEffect;
412   }
413 
addArg(ArgEffects::Factory & af,unsigned idx,ArgEffect e)414   void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e) {
415     Args = af.add(Args, idx, e);
416   }
417 
418   /// setDefaultArgEffect - Set the default argument effect.
setDefaultArgEffect(ArgEffect E)419   void setDefaultArgEffect(ArgEffect E) {
420     DefaultArgEffect = E;
421   }
422 
423   /// getRetEffect - Returns the effect on the return value of the call.
getRetEffect() const424   RetEffect getRetEffect() const { return Ret; }
425 
426   /// setRetEffect - Set the effect of the return value of the call.
setRetEffect(RetEffect E)427   void setRetEffect(RetEffect E) { Ret = E; }
428 
429 
430   /// Sets the effect on the receiver of the message.
setReceiverEffect(ArgEffect e)431   void setReceiverEffect(ArgEffect e) { Receiver = e; }
432 
433   /// getReceiverEffect - Returns the effect on the receiver of the call.
434   ///  This is only meaningful if the summary applies to an ObjCMessageExpr*.
getReceiverEffect() const435   ArgEffect getReceiverEffect() const { return Receiver; }
436 
437   /// Test if two retain summaries are identical. Note that merely equivalent
438   /// summaries are not necessarily identical (for example, if an explicit
439   /// argument effect matches the default effect).
operator ==(const RetainSummary & Other) const440   bool operator==(const RetainSummary &Other) const {
441     return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
442            Receiver == Other.Receiver && Ret == Other.Ret;
443   }
444 
445   /// Profile this summary for inclusion in a FoldingSet.
Profile(llvm::FoldingSetNodeID & ID) const446   void Profile(llvm::FoldingSetNodeID& ID) const {
447     ID.Add(Args);
448     ID.Add(DefaultArgEffect);
449     ID.Add(Receiver);
450     ID.Add(Ret);
451   }
452 
453   /// A retain summary is simple if it has no ArgEffects other than the default.
isSimple() const454   bool isSimple() const {
455     return Args.isEmpty();
456   }
457 
458 private:
getArgEffects() const459   ArgEffects getArgEffects() const { return Args; }
getDefaultArgEffect() const460   ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
461 
462   friend class RetainSummaryManager;
463 };
464 } // end anonymous namespace
465 
466 //===----------------------------------------------------------------------===//
467 // Data structures for constructing summaries.
468 //===----------------------------------------------------------------------===//
469 
470 namespace {
471 class ObjCSummaryKey {
472   IdentifierInfo* II;
473   Selector S;
474 public:
ObjCSummaryKey(IdentifierInfo * ii,Selector s)475   ObjCSummaryKey(IdentifierInfo* ii, Selector s)
476     : II(ii), S(s) {}
477 
ObjCSummaryKey(const ObjCInterfaceDecl * d,Selector s)478   ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s)
479     : II(d ? d->getIdentifier() : nullptr), S(s) {}
480 
ObjCSummaryKey(Selector s)481   ObjCSummaryKey(Selector s)
482     : II(nullptr), S(s) {}
483 
getIdentifier() const484   IdentifierInfo *getIdentifier() const { return II; }
getSelector() const485   Selector getSelector() const { return S; }
486 };
487 }
488 
489 namespace llvm {
490 template <> struct DenseMapInfo<ObjCSummaryKey> {
getEmptyKeyllvm::DenseMapInfo491   static inline ObjCSummaryKey getEmptyKey() {
492     return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
493                           DenseMapInfo<Selector>::getEmptyKey());
494   }
495 
getTombstoneKeyllvm::DenseMapInfo496   static inline ObjCSummaryKey getTombstoneKey() {
497     return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(),
498                           DenseMapInfo<Selector>::getTombstoneKey());
499   }
500 
getHashValuellvm::DenseMapInfo501   static unsigned getHashValue(const ObjCSummaryKey &V) {
502     typedef std::pair<IdentifierInfo*, Selector> PairTy;
503     return DenseMapInfo<PairTy>::getHashValue(PairTy(V.getIdentifier(),
504                                                      V.getSelector()));
505   }
506 
isEqualllvm::DenseMapInfo507   static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
508     return LHS.getIdentifier() == RHS.getIdentifier() &&
509            LHS.getSelector() == RHS.getSelector();
510   }
511 
512 };
513 } // end llvm namespace
514 
515 namespace {
516 class ObjCSummaryCache {
517   typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *> MapTy;
518   MapTy M;
519 public:
ObjCSummaryCache()520   ObjCSummaryCache() {}
521 
find(const ObjCInterfaceDecl * D,Selector S)522   const RetainSummary * find(const ObjCInterfaceDecl *D, Selector S) {
523     // Do a lookup with the (D,S) pair.  If we find a match return
524     // the iterator.
525     ObjCSummaryKey K(D, S);
526     MapTy::iterator I = M.find(K);
527 
528     if (I != M.end())
529       return I->second;
530     if (!D)
531       return nullptr;
532 
533     // Walk the super chain.  If we find a hit with a parent, we'll end
534     // up returning that summary.  We actually allow that key (null,S), as
535     // we cache summaries for the null ObjCInterfaceDecl* to allow us to
536     // generate initial summaries without having to worry about NSObject
537     // being declared.
538     // FIXME: We may change this at some point.
539     for (ObjCInterfaceDecl *C=D->getSuperClass() ;; C=C->getSuperClass()) {
540       if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
541         break;
542 
543       if (!C)
544         return nullptr;
545     }
546 
547     // Cache the summary with original key to make the next lookup faster
548     // and return the iterator.
549     const RetainSummary *Summ = I->second;
550     M[K] = Summ;
551     return Summ;
552   }
553 
find(IdentifierInfo * II,Selector S)554   const RetainSummary *find(IdentifierInfo* II, Selector S) {
555     // FIXME: Class method lookup.  Right now we dont' have a good way
556     // of going between IdentifierInfo* and the class hierarchy.
557     MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
558 
559     if (I == M.end())
560       I = M.find(ObjCSummaryKey(S));
561 
562     return I == M.end() ? nullptr : I->second;
563   }
564 
operator [](ObjCSummaryKey K)565   const RetainSummary *& operator[](ObjCSummaryKey K) {
566     return M[K];
567   }
568 
operator [](Selector S)569   const RetainSummary *& operator[](Selector S) {
570     return M[ ObjCSummaryKey(S) ];
571   }
572 };
573 } // end anonymous namespace
574 
575 //===----------------------------------------------------------------------===//
576 // Data structures for managing collections of summaries.
577 //===----------------------------------------------------------------------===//
578 
579 namespace {
580 class RetainSummaryManager {
581 
582   //==-----------------------------------------------------------------==//
583   //  Typedefs.
584   //==-----------------------------------------------------------------==//
585 
586   typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *>
587           FuncSummariesTy;
588 
589   typedef ObjCSummaryCache ObjCMethodSummariesTy;
590 
591   typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;
592 
593   //==-----------------------------------------------------------------==//
594   //  Data.
595   //==-----------------------------------------------------------------==//
596 
597   /// Ctx - The ASTContext object for the analyzed ASTs.
598   ASTContext &Ctx;
599 
600   /// GCEnabled - Records whether or not the analyzed code runs in GC mode.
601   const bool GCEnabled;
602 
603   /// Records whether or not the analyzed code runs in ARC mode.
604   const bool ARCEnabled;
605 
606   /// FuncSummaries - A map from FunctionDecls to summaries.
607   FuncSummariesTy FuncSummaries;
608 
609   /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
610   ///  to summaries.
611   ObjCMethodSummariesTy ObjCClassMethodSummaries;
612 
613   /// ObjCMethodSummaries - A map from selectors to summaries.
614   ObjCMethodSummariesTy ObjCMethodSummaries;
615 
616   /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
617   ///  and all other data used by the checker.
618   llvm::BumpPtrAllocator BPAlloc;
619 
620   /// AF - A factory for ArgEffects objects.
621   ArgEffects::Factory AF;
622 
623   /// ScratchArgs - A holding buffer for construct ArgEffects.
624   ArgEffects ScratchArgs;
625 
626   /// ObjCAllocRetE - Default return effect for methods returning Objective-C
627   ///  objects.
628   RetEffect ObjCAllocRetE;
629 
630   /// ObjCInitRetE - Default return effect for init methods returning
631   ///   Objective-C objects.
632   RetEffect ObjCInitRetE;
633 
634   /// SimpleSummaries - Used for uniquing summaries that don't have special
635   /// effects.
636   llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
637 
638   //==-----------------------------------------------------------------==//
639   //  Methods.
640   //==-----------------------------------------------------------------==//
641 
642   /// getArgEffects - Returns a persistent ArgEffects object based on the
643   ///  data in ScratchArgs.
644   ArgEffects getArgEffects();
645 
646   enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };
647 
648   const RetainSummary *getUnarySummary(const FunctionType* FT,
649                                        UnaryFuncKind func);
650 
651   const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);
652   const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);
653   const RetainSummary *getCFCreateGetRuleSummary(const FunctionDecl *FD);
654 
655   const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
656 
getPersistentSummary(RetEffect RetEff,ArgEffect ReceiverEff=DoNothing,ArgEffect DefaultEff=MayEscape)657   const RetainSummary *getPersistentSummary(RetEffect RetEff,
658                                             ArgEffect ReceiverEff = DoNothing,
659                                             ArgEffect DefaultEff = MayEscape) {
660     RetainSummary Summ(getArgEffects(), RetEff, DefaultEff, ReceiverEff);
661     return getPersistentSummary(Summ);
662   }
663 
getDoNothingSummary()664   const RetainSummary *getDoNothingSummary() {
665     return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
666   }
667 
getDefaultSummary()668   const RetainSummary *getDefaultSummary() {
669     return getPersistentSummary(RetEffect::MakeNoRet(),
670                                 DoNothing, MayEscape);
671   }
672 
getPersistentStopSummary()673   const RetainSummary *getPersistentStopSummary() {
674     return getPersistentSummary(RetEffect::MakeNoRet(),
675                                 StopTracking, StopTracking);
676   }
677 
678   void InitializeClassMethodSummaries();
679   void InitializeMethodSummaries();
680 private:
addNSObjectClsMethSummary(Selector S,const RetainSummary * Summ)681   void addNSObjectClsMethSummary(Selector S, const RetainSummary *Summ) {
682     ObjCClassMethodSummaries[S] = Summ;
683   }
684 
addNSObjectMethSummary(Selector S,const RetainSummary * Summ)685   void addNSObjectMethSummary(Selector S, const RetainSummary *Summ) {
686     ObjCMethodSummaries[S] = Summ;
687   }
688 
addClassMethSummary(const char * Cls,const char * name,const RetainSummary * Summ,bool isNullary=true)689   void addClassMethSummary(const char* Cls, const char* name,
690                            const RetainSummary *Summ, bool isNullary = true) {
691     IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
692     Selector S = isNullary ? GetNullarySelector(name, Ctx)
693                            : GetUnarySelector(name, Ctx);
694     ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
695   }
696 
addInstMethSummary(const char * Cls,const char * nullaryName,const RetainSummary * Summ)697   void addInstMethSummary(const char* Cls, const char* nullaryName,
698                           const RetainSummary *Summ) {
699     IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
700     Selector S = GetNullarySelector(nullaryName, Ctx);
701     ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
702   }
703 
addMethodSummary(IdentifierInfo * ClsII,ObjCMethodSummariesTy & Summaries,const RetainSummary * Summ,va_list argp)704   void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
705                         const RetainSummary *Summ, va_list argp) {
706     Selector S = getKeywordSelector(Ctx, argp);
707     Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
708   }
709 
addInstMethSummary(const char * Cls,const RetainSummary * Summ,...)710   void addInstMethSummary(const char* Cls, const RetainSummary * Summ, ...) {
711     va_list argp;
712     va_start(argp, Summ);
713     addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp);
714     va_end(argp);
715   }
716 
addClsMethSummary(const char * Cls,const RetainSummary * Summ,...)717   void addClsMethSummary(const char* Cls, const RetainSummary * Summ, ...) {
718     va_list argp;
719     va_start(argp, Summ);
720     addMethodSummary(&Ctx.Idents.get(Cls),ObjCClassMethodSummaries, Summ, argp);
721     va_end(argp);
722   }
723 
addClsMethSummary(IdentifierInfo * II,const RetainSummary * Summ,...)724   void addClsMethSummary(IdentifierInfo *II, const RetainSummary * Summ, ...) {
725     va_list argp;
726     va_start(argp, Summ);
727     addMethodSummary(II, ObjCClassMethodSummaries, Summ, argp);
728     va_end(argp);
729   }
730 
731 public:
732 
RetainSummaryManager(ASTContext & ctx,bool gcenabled,bool usesARC)733   RetainSummaryManager(ASTContext &ctx, bool gcenabled, bool usesARC)
734    : Ctx(ctx),
735      GCEnabled(gcenabled),
736      ARCEnabled(usesARC),
737      AF(BPAlloc), ScratchArgs(AF.getEmptyMap()),
738      ObjCAllocRetE(gcenabled
739                     ? RetEffect::MakeGCNotOwned()
740                     : (usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
741                                : RetEffect::MakeOwned(RetEffect::ObjC, true))),
742      ObjCInitRetE(gcenabled
743                     ? RetEffect::MakeGCNotOwned()
744                     : (usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
745                                : RetEffect::MakeOwnedWhenTrackedReceiver())) {
746     InitializeClassMethodSummaries();
747     InitializeMethodSummaries();
748   }
749 
750   const RetainSummary *getSummary(const CallEvent &Call,
751                                   ProgramStateRef State = nullptr);
752 
753   const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
754 
755   const RetainSummary *getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
756                                         const ObjCMethodDecl *MD,
757                                         QualType RetTy,
758                                         ObjCMethodSummariesTy &CachedSummaries);
759 
760   const RetainSummary *getInstanceMethodSummary(const ObjCMethodCall &M,
761                                                 ProgramStateRef State);
762 
getClassMethodSummary(const ObjCMethodCall & M)763   const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) {
764     assert(!M.isInstanceMessage());
765     const ObjCInterfaceDecl *Class = M.getReceiverInterface();
766 
767     return getMethodSummary(M.getSelector(), Class, M.getDecl(),
768                             M.getResultType(), ObjCClassMethodSummaries);
769   }
770 
771   /// getMethodSummary - This version of getMethodSummary is used to query
772   ///  the summary for the current method being analyzed.
getMethodSummary(const ObjCMethodDecl * MD)773   const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {
774     const ObjCInterfaceDecl *ID = MD->getClassInterface();
775     Selector S = MD->getSelector();
776     QualType ResultTy = MD->getReturnType();
777 
778     ObjCMethodSummariesTy *CachedSummaries;
779     if (MD->isInstanceMethod())
780       CachedSummaries = &ObjCMethodSummaries;
781     else
782       CachedSummaries = &ObjCClassMethodSummaries;
783 
784     return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
785   }
786 
787   const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD,
788                                                 Selector S, QualType RetTy);
789 
790   /// Determine if there is a special return effect for this function or method.
791   Optional<RetEffect> getRetEffectFromAnnotations(QualType RetTy,
792                                                   const Decl *D);
793 
794   void updateSummaryFromAnnotations(const RetainSummary *&Summ,
795                                     const ObjCMethodDecl *MD);
796 
797   void updateSummaryFromAnnotations(const RetainSummary *&Summ,
798                                     const FunctionDecl *FD);
799 
800   void updateSummaryForCall(const RetainSummary *&Summ,
801                             const CallEvent &Call);
802 
isGCEnabled() const803   bool isGCEnabled() const { return GCEnabled; }
804 
isARCEnabled() const805   bool isARCEnabled() const { return ARCEnabled; }
806 
isARCorGCEnabled() const807   bool isARCorGCEnabled() const { return GCEnabled || ARCEnabled; }
808 
getObjAllocRetEffect() const809   RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
810 
811   friend class RetainSummaryTemplate;
812 };
813 
814 // Used to avoid allocating long-term (BPAlloc'd) memory for default retain
815 // summaries. If a function or method looks like it has a default summary, but
816 // it has annotations, the annotations are added to the stack-based template
817 // and then copied into managed memory.
818 class RetainSummaryTemplate {
819   RetainSummaryManager &Manager;
820   const RetainSummary *&RealSummary;
821   RetainSummary ScratchSummary;
822   bool Accessed;
823 public:
RetainSummaryTemplate(const RetainSummary * & real,RetainSummaryManager & mgr)824   RetainSummaryTemplate(const RetainSummary *&real, RetainSummaryManager &mgr)
825     : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(false) {}
826 
~RetainSummaryTemplate()827   ~RetainSummaryTemplate() {
828     if (Accessed)
829       RealSummary = Manager.getPersistentSummary(ScratchSummary);
830   }
831 
operator *()832   RetainSummary &operator*() {
833     Accessed = true;
834     return ScratchSummary;
835   }
836 
operator ->()837   RetainSummary *operator->() {
838     Accessed = true;
839     return &ScratchSummary;
840   }
841 };
842 
843 } // end anonymous namespace
844 
845 //===----------------------------------------------------------------------===//
846 // Implementation of checker data structures.
847 //===----------------------------------------------------------------------===//
848 
getArgEffects()849 ArgEffects RetainSummaryManager::getArgEffects() {
850   ArgEffects AE = ScratchArgs;
851   ScratchArgs = AF.getEmptyMap();
852   return AE;
853 }
854 
855 const RetainSummary *
getPersistentSummary(const RetainSummary & OldSumm)856 RetainSummaryManager::getPersistentSummary(const RetainSummary &OldSumm) {
857   // Unique "simple" summaries -- those without ArgEffects.
858   if (OldSumm.isSimple()) {
859     llvm::FoldingSetNodeID ID;
860     OldSumm.Profile(ID);
861 
862     void *Pos;
863     CachedSummaryNode *N = SimpleSummaries.FindNodeOrInsertPos(ID, Pos);
864 
865     if (!N) {
866       N = (CachedSummaryNode *) BPAlloc.Allocate<CachedSummaryNode>();
867       new (N) CachedSummaryNode(OldSumm);
868       SimpleSummaries.InsertNode(N, Pos);
869     }
870 
871     return &N->getValue();
872   }
873 
874   RetainSummary *Summ = (RetainSummary *) BPAlloc.Allocate<RetainSummary>();
875   new (Summ) RetainSummary(OldSumm);
876   return Summ;
877 }
878 
879 //===----------------------------------------------------------------------===//
880 // Summary creation for functions (largely uses of Core Foundation).
881 //===----------------------------------------------------------------------===//
882 
isRetain(const FunctionDecl * FD,StringRef FName)883 static bool isRetain(const FunctionDecl *FD, StringRef FName) {
884   return FName.endswith("Retain");
885 }
886 
isRelease(const FunctionDecl * FD,StringRef FName)887 static bool isRelease(const FunctionDecl *FD, StringRef FName) {
888   return FName.endswith("Release");
889 }
890 
isAutorelease(const FunctionDecl * FD,StringRef FName)891 static bool isAutorelease(const FunctionDecl *FD, StringRef FName) {
892   return FName.endswith("Autorelease");
893 }
894 
isMakeCollectable(const FunctionDecl * FD,StringRef FName)895 static bool isMakeCollectable(const FunctionDecl *FD, StringRef FName) {
896   // FIXME: Remove FunctionDecl parameter.
897   // FIXME: Is it really okay if MakeCollectable isn't a suffix?
898   return FName.find("MakeCollectable") != StringRef::npos;
899 }
900 
getStopTrackingHardEquivalent(ArgEffect E)901 static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
902   switch (E) {
903   case DoNothing:
904   case Autorelease:
905   case DecRefBridgedTransferred:
906   case IncRef:
907   case IncRefMsg:
908   case MakeCollectable:
909   case MayEscape:
910   case StopTracking:
911   case StopTrackingHard:
912     return StopTrackingHard;
913   case DecRef:
914   case DecRefAndStopTrackingHard:
915     return DecRefAndStopTrackingHard;
916   case DecRefMsg:
917   case DecRefMsgAndStopTrackingHard:
918     return DecRefMsgAndStopTrackingHard;
919   case Dealloc:
920     return Dealloc;
921   }
922 
923   llvm_unreachable("Unknown ArgEffect kind");
924 }
925 
updateSummaryForCall(const RetainSummary * & S,const CallEvent & Call)926 void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
927                                                 const CallEvent &Call) {
928   if (Call.hasNonZeroCallbackArg()) {
929     ArgEffect RecEffect =
930       getStopTrackingHardEquivalent(S->getReceiverEffect());
931     ArgEffect DefEffect =
932       getStopTrackingHardEquivalent(S->getDefaultArgEffect());
933 
934     ArgEffects CustomArgEffects = S->getArgEffects();
935     for (ArgEffects::iterator I = CustomArgEffects.begin(),
936                               E = CustomArgEffects.end();
937          I != E; ++I) {
938       ArgEffect Translated = getStopTrackingHardEquivalent(I->second);
939       if (Translated != DefEffect)
940         ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
941     }
942 
943     RetEffect RE = RetEffect::MakeNoRetHard();
944 
945     // Special cases where the callback argument CANNOT free the return value.
946     // This can generally only happen if we know that the callback will only be
947     // called when the return value is already being deallocated.
948     if (const SimpleFunctionCall *FC = dyn_cast<SimpleFunctionCall>(&Call)) {
949       if (IdentifierInfo *Name = FC->getDecl()->getIdentifier()) {
950         // When the CGBitmapContext is deallocated, the callback here will free
951         // the associated data buffer.
952         if (Name->isStr("CGBitmapContextCreateWithData"))
953           RE = S->getRetEffect();
954       }
955     }
956 
957     S = getPersistentSummary(RE, RecEffect, DefEffect);
958   }
959 
960   // Special case '[super init];' and '[self init];'
961   //
962   // Even though calling '[super init]' without assigning the result to self
963   // and checking if the parent returns 'nil' is a bad pattern, it is common.
964   // Additionally, our Self Init checker already warns about it. To avoid
965   // overwhelming the user with messages from both checkers, we model the case
966   // of '[super init]' in cases when it is not consumed by another expression
967   // as if the call preserves the value of 'self'; essentially, assuming it can
968   // never fail and return 'nil'.
969   // Note, we don't want to just stop tracking the value since we want the
970   // RetainCount checker to report leaks and use-after-free if SelfInit checker
971   // is turned off.
972   if (const ObjCMethodCall *MC = dyn_cast<ObjCMethodCall>(&Call)) {
973     if (MC->getMethodFamily() == OMF_init && MC->isReceiverSelfOrSuper()) {
974 
975       // Check if the message is not consumed, we know it will not be used in
976       // an assignment, ex: "self = [super init]".
977       const Expr *ME = MC->getOriginExpr();
978       const LocationContext *LCtx = MC->getLocationContext();
979       ParentMap &PM = LCtx->getAnalysisDeclContext()->getParentMap();
980       if (!PM.isConsumedExpr(ME)) {
981         RetainSummaryTemplate ModifiableSummaryTemplate(S, *this);
982         ModifiableSummaryTemplate->setReceiverEffect(DoNothing);
983         ModifiableSummaryTemplate->setRetEffect(RetEffect::MakeNoRet());
984       }
985     }
986 
987   }
988 }
989 
990 const RetainSummary *
getSummary(const CallEvent & Call,ProgramStateRef State)991 RetainSummaryManager::getSummary(const CallEvent &Call,
992                                  ProgramStateRef State) {
993   const RetainSummary *Summ;
994   switch (Call.getKind()) {
995   case CE_Function:
996     Summ = getFunctionSummary(cast<SimpleFunctionCall>(Call).getDecl());
997     break;
998   case CE_CXXMember:
999   case CE_CXXMemberOperator:
1000   case CE_Block:
1001   case CE_CXXConstructor:
1002   case CE_CXXDestructor:
1003   case CE_CXXAllocator:
1004     // FIXME: These calls are currently unsupported.
1005     return getPersistentStopSummary();
1006   case CE_ObjCMessage: {
1007     const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
1008     if (Msg.isInstanceMessage())
1009       Summ = getInstanceMethodSummary(Msg, State);
1010     else
1011       Summ = getClassMethodSummary(Msg);
1012     break;
1013   }
1014   }
1015 
1016   updateSummaryForCall(Summ, Call);
1017 
1018   assert(Summ && "Unknown call type?");
1019   return Summ;
1020 }
1021 
1022 const RetainSummary *
getFunctionSummary(const FunctionDecl * FD)1023 RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {
1024   // If we don't know what function we're calling, use our default summary.
1025   if (!FD)
1026     return getDefaultSummary();
1027 
1028   // Look up a summary in our cache of FunctionDecls -> Summaries.
1029   FuncSummariesTy::iterator I = FuncSummaries.find(FD);
1030   if (I != FuncSummaries.end())
1031     return I->second;
1032 
1033   // No summary?  Generate one.
1034   const RetainSummary *S = nullptr;
1035   bool AllowAnnotations = true;
1036 
1037   do {
1038     // We generate "stop" summaries for implicitly defined functions.
1039     if (FD->isImplicit()) {
1040       S = getPersistentStopSummary();
1041       break;
1042     }
1043 
1044     // [PR 3337] Use 'getAs<FunctionType>' to strip away any typedefs on the
1045     // function's type.
1046     const FunctionType* FT = FD->getType()->getAs<FunctionType>();
1047     const IdentifierInfo *II = FD->getIdentifier();
1048     if (!II)
1049       break;
1050 
1051     StringRef FName = II->getName();
1052 
1053     // Strip away preceding '_'.  Doing this here will effect all the checks
1054     // down below.
1055     FName = FName.substr(FName.find_first_not_of('_'));
1056 
1057     // Inspect the result type.
1058     QualType RetTy = FT->getReturnType();
1059 
1060     // FIXME: This should all be refactored into a chain of "summary lookup"
1061     //  filters.
1062     assert(ScratchArgs.isEmpty());
1063 
1064     if (FName == "pthread_create" || FName == "pthread_setspecific") {
1065       // Part of: <rdar://problem/7299394> and <rdar://problem/11282706>.
1066       // This will be addressed better with IPA.
1067       S = getPersistentStopSummary();
1068     } else if (FName == "NSMakeCollectable") {
1069       // Handle: id NSMakeCollectable(CFTypeRef)
1070       S = (RetTy->isObjCIdType())
1071           ? getUnarySummary(FT, cfmakecollectable)
1072           : getPersistentStopSummary();
1073       // The headers on OS X 10.8 use cf_consumed/ns_returns_retained,
1074       // but we can fully model NSMakeCollectable ourselves.
1075       AllowAnnotations = false;
1076     } else if (FName == "CFPlugInInstanceCreate") {
1077       S = getPersistentSummary(RetEffect::MakeNoRet());
1078     } else if (FName == "IOBSDNameMatching" ||
1079                FName == "IOServiceMatching" ||
1080                FName == "IOServiceNameMatching" ||
1081                FName == "IORegistryEntrySearchCFProperty" ||
1082                FName == "IORegistryEntryIDMatching" ||
1083                FName == "IOOpenFirmwarePathMatching") {
1084       // Part of <rdar://problem/6961230>. (IOKit)
1085       // This should be addressed using a API table.
1086       S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
1087                                DoNothing, DoNothing);
1088     } else if (FName == "IOServiceGetMatchingService" ||
1089                FName == "IOServiceGetMatchingServices") {
1090       // FIXES: <rdar://problem/6326900>
1091       // This should be addressed using a API table.  This strcmp is also
1092       // a little gross, but there is no need to super optimize here.
1093       ScratchArgs = AF.add(ScratchArgs, 1, DecRef);
1094       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
1095     } else if (FName == "IOServiceAddNotification" ||
1096                FName == "IOServiceAddMatchingNotification") {
1097       // Part of <rdar://problem/6961230>. (IOKit)
1098       // This should be addressed using a API table.
1099       ScratchArgs = AF.add(ScratchArgs, 2, DecRef);
1100       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
1101     } else if (FName == "CVPixelBufferCreateWithBytes") {
1102       // FIXES: <rdar://problem/7283567>
1103       // Eventually this can be improved by recognizing that the pixel
1104       // buffer passed to CVPixelBufferCreateWithBytes is released via
1105       // a callback and doing full IPA to make sure this is done correctly.
1106       // FIXME: This function has an out parameter that returns an
1107       // allocated object.
1108       ScratchArgs = AF.add(ScratchArgs, 7, StopTracking);
1109       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
1110     } else if (FName == "CGBitmapContextCreateWithData") {
1111       // FIXES: <rdar://problem/7358899>
1112       // Eventually this can be improved by recognizing that 'releaseInfo'
1113       // passed to CGBitmapContextCreateWithData is released via
1114       // a callback and doing full IPA to make sure this is done correctly.
1115       ScratchArgs = AF.add(ScratchArgs, 8, StopTracking);
1116       S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
1117                                DoNothing, DoNothing);
1118     } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
1119       // FIXES: <rdar://problem/7283567>
1120       // Eventually this can be improved by recognizing that the pixel
1121       // buffer passed to CVPixelBufferCreateWithPlanarBytes is released
1122       // via a callback and doing full IPA to make sure this is done
1123       // correctly.
1124       ScratchArgs = AF.add(ScratchArgs, 12, StopTracking);
1125       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
1126     } else if (FName == "dispatch_set_context" ||
1127                FName == "xpc_connection_set_context") {
1128       // <rdar://problem/11059275> - The analyzer currently doesn't have
1129       // a good way to reason about the finalizer function for libdispatch.
1130       // If we pass a context object that is memory managed, stop tracking it.
1131       // <rdar://problem/13783514> - Same problem, but for XPC.
1132       // FIXME: this hack should possibly go away once we can handle
1133       // libdispatch and XPC finalizers.
1134       ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
1135       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
1136     } else if (FName.startswith("NSLog")) {
1137       S = getDoNothingSummary();
1138     } else if (FName.startswith("NS") &&
1139                 (FName.find("Insert") != StringRef::npos)) {
1140       // Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
1141       // be deallocated by NSMapRemove. (radar://11152419)
1142       ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
1143       ScratchArgs = AF.add(ScratchArgs, 2, StopTracking);
1144       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
1145     }
1146 
1147     // Did we get a summary?
1148     if (S)
1149       break;
1150 
1151     if (RetTy->isPointerType()) {
1152       // For CoreFoundation ('CF') types.
1153       if (cocoa::isRefType(RetTy, "CF", FName)) {
1154         if (isRetain(FD, FName)) {
1155           S = getUnarySummary(FT, cfretain);
1156         } else if (isAutorelease(FD, FName)) {
1157           S = getUnarySummary(FT, cfautorelease);
1158           // The headers use cf_consumed, but we can fully model CFAutorelease
1159           // ourselves.
1160           AllowAnnotations = false;
1161         } else if (isMakeCollectable(FD, FName)) {
1162           S = getUnarySummary(FT, cfmakecollectable);
1163           AllowAnnotations = false;
1164         } else {
1165           S = getCFCreateGetRuleSummary(FD);
1166         }
1167 
1168         break;
1169       }
1170 
1171       // For CoreGraphics ('CG') types.
1172       if (cocoa::isRefType(RetTy, "CG", FName)) {
1173         if (isRetain(FD, FName))
1174           S = getUnarySummary(FT, cfretain);
1175         else
1176           S = getCFCreateGetRuleSummary(FD);
1177 
1178         break;
1179       }
1180 
1181       // For the Disk Arbitration API (DiskArbitration/DADisk.h)
1182       if (cocoa::isRefType(RetTy, "DADisk") ||
1183           cocoa::isRefType(RetTy, "DADissenter") ||
1184           cocoa::isRefType(RetTy, "DASessionRef")) {
1185         S = getCFCreateGetRuleSummary(FD);
1186         break;
1187       }
1188 
1189       if (FD->hasAttr<CFAuditedTransferAttr>()) {
1190         S = getCFCreateGetRuleSummary(FD);
1191         break;
1192       }
1193 
1194       break;
1195     }
1196 
1197     // Check for release functions, the only kind of functions that we care
1198     // about that don't return a pointer type.
1199     if (FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) {
1200       // Test for 'CGCF'.
1201       FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);
1202 
1203       if (isRelease(FD, FName))
1204         S = getUnarySummary(FT, cfrelease);
1205       else {
1206         assert (ScratchArgs.isEmpty());
1207         // Remaining CoreFoundation and CoreGraphics functions.
1208         // We use to assume that they all strictly followed the ownership idiom
1209         // and that ownership cannot be transferred.  While this is technically
1210         // correct, many methods allow a tracked object to escape.  For example:
1211         //
1212         //   CFMutableDictionaryRef x = CFDictionaryCreateMutable(...);
1213         //   CFDictionaryAddValue(y, key, x);
1214         //   CFRelease(x);
1215         //   ... it is okay to use 'x' since 'y' has a reference to it
1216         //
1217         // We handle this and similar cases with the follow heuristic.  If the
1218         // function name contains "InsertValue", "SetValue", "AddValue",
1219         // "AppendValue", or "SetAttribute", then we assume that arguments may
1220         // "escape."  This means that something else holds on to the object,
1221         // allowing it be used even after its local retain count drops to 0.
1222         ArgEffect E = (StrInStrNoCase(FName, "InsertValue") != StringRef::npos||
1223                        StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
1224                        StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
1225                        StrInStrNoCase(FName, "AppendValue") != StringRef::npos||
1226                        StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)
1227                       ? MayEscape : DoNothing;
1228 
1229         S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E);
1230       }
1231     }
1232   }
1233   while (0);
1234 
1235   // If we got all the way here without any luck, use a default summary.
1236   if (!S)
1237     S = getDefaultSummary();
1238 
1239   // Annotations override defaults.
1240   if (AllowAnnotations)
1241     updateSummaryFromAnnotations(S, FD);
1242 
1243   FuncSummaries[FD] = S;
1244   return S;
1245 }
1246 
1247 const RetainSummary *
getCFCreateGetRuleSummary(const FunctionDecl * FD)1248 RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl *FD) {
1249   if (coreFoundation::followsCreateRule(FD))
1250     return getCFSummaryCreateRule(FD);
1251 
1252   return getCFSummaryGetRule(FD);
1253 }
1254 
1255 const RetainSummary *
getUnarySummary(const FunctionType * FT,UnaryFuncKind func)1256 RetainSummaryManager::getUnarySummary(const FunctionType* FT,
1257                                       UnaryFuncKind func) {
1258 
1259   // Sanity check that this is *really* a unary function.  This can
1260   // happen if people do weird things.
1261   const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);
1262   if (!FTP || FTP->getNumParams() != 1)
1263     return getPersistentStopSummary();
1264 
1265   assert (ScratchArgs.isEmpty());
1266 
1267   ArgEffect Effect;
1268   switch (func) {
1269   case cfretain: Effect = IncRef; break;
1270   case cfrelease: Effect = DecRef; break;
1271   case cfautorelease: Effect = Autorelease; break;
1272   case cfmakecollectable: Effect = MakeCollectable; break;
1273   }
1274 
1275   ScratchArgs = AF.add(ScratchArgs, 0, Effect);
1276   return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
1277 }
1278 
1279 const RetainSummary *
getCFSummaryCreateRule(const FunctionDecl * FD)1280 RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) {
1281   assert (ScratchArgs.isEmpty());
1282 
1283   return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
1284 }
1285 
1286 const RetainSummary *
getCFSummaryGetRule(const FunctionDecl * FD)1287 RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
1288   assert (ScratchArgs.isEmpty());
1289   return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
1290                               DoNothing, DoNothing);
1291 }
1292 
1293 //===----------------------------------------------------------------------===//
1294 // Summary creation for Selectors.
1295 //===----------------------------------------------------------------------===//
1296 
1297 Optional<RetEffect>
getRetEffectFromAnnotations(QualType RetTy,const Decl * D)1298 RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
1299                                                   const Decl *D) {
1300   if (cocoa::isCocoaObjectRef(RetTy)) {
1301     if (D->hasAttr<NSReturnsRetainedAttr>())
1302       return ObjCAllocRetE;
1303 
1304     if (D->hasAttr<NSReturnsNotRetainedAttr>() ||
1305         D->hasAttr<NSReturnsAutoreleasedAttr>())
1306       return RetEffect::MakeNotOwned(RetEffect::ObjC);
1307 
1308   } else if (!RetTy->isPointerType()) {
1309     return None;
1310   }
1311 
1312   if (D->hasAttr<CFReturnsRetainedAttr>())
1313     return RetEffect::MakeOwned(RetEffect::CF, true);
1314 
1315   if (D->hasAttr<CFReturnsNotRetainedAttr>())
1316     return RetEffect::MakeNotOwned(RetEffect::CF);
1317 
1318   return None;
1319 }
1320 
1321 void
updateSummaryFromAnnotations(const RetainSummary * & Summ,const FunctionDecl * FD)1322 RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
1323                                                    const FunctionDecl *FD) {
1324   if (!FD)
1325     return;
1326 
1327   assert(Summ && "Must have a summary to add annotations to.");
1328   RetainSummaryTemplate Template(Summ, *this);
1329 
1330   // Effects on the parameters.
1331   unsigned parm_idx = 0;
1332   for (FunctionDecl::param_const_iterator pi = FD->param_begin(),
1333          pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
1334     const ParmVarDecl *pd = *pi;
1335     if (pd->hasAttr<NSConsumedAttr>())
1336       Template->addArg(AF, parm_idx, DecRefMsg);
1337     else if (pd->hasAttr<CFConsumedAttr>())
1338       Template->addArg(AF, parm_idx, DecRef);
1339   }
1340 
1341   QualType RetTy = FD->getReturnType();
1342   if (Optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, FD))
1343     Template->setRetEffect(*RetE);
1344 }
1345 
1346 void
updateSummaryFromAnnotations(const RetainSummary * & Summ,const ObjCMethodDecl * MD)1347 RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
1348                                                    const ObjCMethodDecl *MD) {
1349   if (!MD)
1350     return;
1351 
1352   assert(Summ && "Must have a valid summary to add annotations to");
1353   RetainSummaryTemplate Template(Summ, *this);
1354 
1355   // Effects on the receiver.
1356   if (MD->hasAttr<NSConsumesSelfAttr>())
1357     Template->setReceiverEffect(DecRefMsg);
1358 
1359   // Effects on the parameters.
1360   unsigned parm_idx = 0;
1361   for (ObjCMethodDecl::param_const_iterator
1362          pi=MD->param_begin(), pe=MD->param_end();
1363        pi != pe; ++pi, ++parm_idx) {
1364     const ParmVarDecl *pd = *pi;
1365     if (pd->hasAttr<NSConsumedAttr>())
1366       Template->addArg(AF, parm_idx, DecRefMsg);
1367     else if (pd->hasAttr<CFConsumedAttr>()) {
1368       Template->addArg(AF, parm_idx, DecRef);
1369     }
1370   }
1371 
1372   QualType RetTy = MD->getReturnType();
1373   if (Optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, MD))
1374     Template->setRetEffect(*RetE);
1375 }
1376 
1377 const RetainSummary *
getStandardMethodSummary(const ObjCMethodDecl * MD,Selector S,QualType RetTy)1378 RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
1379                                                Selector S, QualType RetTy) {
1380   // Any special effects?
1381   ArgEffect ReceiverEff = DoNothing;
1382   RetEffect ResultEff = RetEffect::MakeNoRet();
1383 
1384   // Check the method family, and apply any default annotations.
1385   switch (MD ? MD->getMethodFamily() : S.getMethodFamily()) {
1386     case OMF_None:
1387     case OMF_initialize:
1388     case OMF_performSelector:
1389       // Assume all Objective-C methods follow Cocoa Memory Management rules.
1390       // FIXME: Does the non-threaded performSelector family really belong here?
1391       // The selector could be, say, @selector(copy).
1392       if (cocoa::isCocoaObjectRef(RetTy))
1393         ResultEff = RetEffect::MakeNotOwned(RetEffect::ObjC);
1394       else if (coreFoundation::isCFObjectRef(RetTy)) {
1395         // ObjCMethodDecl currently doesn't consider CF objects as valid return
1396         // values for alloc, new, copy, or mutableCopy, so we have to
1397         // double-check with the selector. This is ugly, but there aren't that
1398         // many Objective-C methods that return CF objects, right?
1399         if (MD) {
1400           switch (S.getMethodFamily()) {
1401           case OMF_alloc:
1402           case OMF_new:
1403           case OMF_copy:
1404           case OMF_mutableCopy:
1405             ResultEff = RetEffect::MakeOwned(RetEffect::CF, true);
1406             break;
1407           default:
1408             ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);
1409             break;
1410           }
1411         } else {
1412           ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);
1413         }
1414       }
1415       break;
1416     case OMF_init:
1417       ResultEff = ObjCInitRetE;
1418       ReceiverEff = DecRefMsg;
1419       break;
1420     case OMF_alloc:
1421     case OMF_new:
1422     case OMF_copy:
1423     case OMF_mutableCopy:
1424       if (cocoa::isCocoaObjectRef(RetTy))
1425         ResultEff = ObjCAllocRetE;
1426       else if (coreFoundation::isCFObjectRef(RetTy))
1427         ResultEff = RetEffect::MakeOwned(RetEffect::CF, true);
1428       break;
1429     case OMF_autorelease:
1430       ReceiverEff = Autorelease;
1431       break;
1432     case OMF_retain:
1433       ReceiverEff = IncRefMsg;
1434       break;
1435     case OMF_release:
1436       ReceiverEff = DecRefMsg;
1437       break;
1438     case OMF_dealloc:
1439       ReceiverEff = Dealloc;
1440       break;
1441     case OMF_self:
1442       // -self is handled specially by the ExprEngine to propagate the receiver.
1443       break;
1444     case OMF_retainCount:
1445     case OMF_finalize:
1446       // These methods don't return objects.
1447       break;
1448   }
1449 
1450   // If one of the arguments in the selector has the keyword 'delegate' we
1451   // should stop tracking the reference count for the receiver.  This is
1452   // because the reference count is quite possibly handled by a delegate
1453   // method.
1454   if (S.isKeywordSelector()) {
1455     for (unsigned i = 0, e = S.getNumArgs(); i != e; ++i) {
1456       StringRef Slot = S.getNameForSlot(i);
1457       if (Slot.substr(Slot.size() - 8).equals_lower("delegate")) {
1458         if (ResultEff == ObjCInitRetE)
1459           ResultEff = RetEffect::MakeNoRetHard();
1460         else
1461           ReceiverEff = StopTrackingHard;
1462       }
1463     }
1464   }
1465 
1466   if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing &&
1467       ResultEff.getKind() == RetEffect::NoRet)
1468     return getDefaultSummary();
1469 
1470   return getPersistentSummary(ResultEff, ReceiverEff, MayEscape);
1471 }
1472 
1473 const RetainSummary *
getInstanceMethodSummary(const ObjCMethodCall & Msg,ProgramStateRef State)1474 RetainSummaryManager::getInstanceMethodSummary(const ObjCMethodCall &Msg,
1475                                                ProgramStateRef State) {
1476   const ObjCInterfaceDecl *ReceiverClass = nullptr;
1477 
1478   // We do better tracking of the type of the object than the core ExprEngine.
1479   // See if we have its type in our private state.
1480   // FIXME: Eventually replace the use of state->get<RefBindings> with
1481   // a generic API for reasoning about the Objective-C types of symbolic
1482   // objects.
1483   SVal ReceiverV = Msg.getReceiverSVal();
1484   if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
1485     if (const RefVal *T = getRefBinding(State, Sym))
1486       if (const ObjCObjectPointerType *PT =
1487             T->getType()->getAs<ObjCObjectPointerType>())
1488         ReceiverClass = PT->getInterfaceDecl();
1489 
1490   // If we don't know what kind of object this is, fall back to its static type.
1491   if (!ReceiverClass)
1492     ReceiverClass = Msg.getReceiverInterface();
1493 
1494   // FIXME: The receiver could be a reference to a class, meaning that
1495   //  we should use the class method.
1496   // id x = [NSObject class];
1497   // [x performSelector:... withObject:... afterDelay:...];
1498   Selector S = Msg.getSelector();
1499   const ObjCMethodDecl *Method = Msg.getDecl();
1500   if (!Method && ReceiverClass)
1501     Method = ReceiverClass->getInstanceMethod(S);
1502 
1503   return getMethodSummary(S, ReceiverClass, Method, Msg.getResultType(),
1504                           ObjCMethodSummaries);
1505 }
1506 
1507 const RetainSummary *
getMethodSummary(Selector S,const ObjCInterfaceDecl * ID,const ObjCMethodDecl * MD,QualType RetTy,ObjCMethodSummariesTy & CachedSummaries)1508 RetainSummaryManager::getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
1509                                        const ObjCMethodDecl *MD, QualType RetTy,
1510                                        ObjCMethodSummariesTy &CachedSummaries) {
1511 
1512   // Look up a summary in our summary cache.
1513   const RetainSummary *Summ = CachedSummaries.find(ID, S);
1514 
1515   if (!Summ) {
1516     Summ = getStandardMethodSummary(MD, S, RetTy);
1517 
1518     // Annotations override defaults.
1519     updateSummaryFromAnnotations(Summ, MD);
1520 
1521     // Memoize the summary.
1522     CachedSummaries[ObjCSummaryKey(ID, S)] = Summ;
1523   }
1524 
1525   return Summ;
1526 }
1527 
InitializeClassMethodSummaries()1528 void RetainSummaryManager::InitializeClassMethodSummaries() {
1529   assert(ScratchArgs.isEmpty());
1530   // Create the [NSAssertionHandler currentHander] summary.
1531   addClassMethSummary("NSAssertionHandler", "currentHandler",
1532                 getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC)));
1533 
1534   // Create the [NSAutoreleasePool addObject:] summary.
1535   ScratchArgs = AF.add(ScratchArgs, 0, Autorelease);
1536   addClassMethSummary("NSAutoreleasePool", "addObject",
1537                       getPersistentSummary(RetEffect::MakeNoRet(),
1538                                            DoNothing, Autorelease));
1539 }
1540 
InitializeMethodSummaries()1541 void RetainSummaryManager::InitializeMethodSummaries() {
1542 
1543   assert (ScratchArgs.isEmpty());
1544 
1545   // Create the "init" selector.  It just acts as a pass-through for the
1546   // receiver.
1547   const RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE, DecRefMsg);
1548   addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
1549 
1550   // awakeAfterUsingCoder: behaves basically like an 'init' method.  It
1551   // claims the receiver and returns a retained object.
1552   addNSObjectMethSummary(GetUnarySelector("awakeAfterUsingCoder", Ctx),
1553                          InitSumm);
1554 
1555   // The next methods are allocators.
1556   const RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE);
1557   const RetainSummary *CFAllocSumm =
1558     getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
1559 
1560   // Create the "retain" selector.
1561   RetEffect NoRet = RetEffect::MakeNoRet();
1562   const RetainSummary *Summ = getPersistentSummary(NoRet, IncRefMsg);
1563   addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
1564 
1565   // Create the "release" selector.
1566   Summ = getPersistentSummary(NoRet, DecRefMsg);
1567   addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
1568 
1569   // Create the -dealloc summary.
1570   Summ = getPersistentSummary(NoRet, Dealloc);
1571   addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ);
1572 
1573   // Create the "autorelease" selector.
1574   Summ = getPersistentSummary(NoRet, Autorelease);
1575   addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
1576 
1577   // For NSWindow, allocated objects are (initially) self-owned.
1578   // FIXME: For now we opt for false negatives with NSWindow, as these objects
1579   //  self-own themselves.  However, they only do this once they are displayed.
1580   //  Thus, we need to track an NSWindow's display status.
1581   //  This is tracked in <rdar://problem/6062711>.
1582   //  See also http://llvm.org/bugs/show_bug.cgi?id=3714.
1583   const RetainSummary *NoTrackYet = getPersistentSummary(RetEffect::MakeNoRet(),
1584                                                    StopTracking,
1585                                                    StopTracking);
1586 
1587   addClassMethSummary("NSWindow", "alloc", NoTrackYet);
1588 
1589   // For NSPanel (which subclasses NSWindow), allocated objects are not
1590   //  self-owned.
1591   // FIXME: For now we don't track NSPanels. object for the same reason
1592   //   as for NSWindow objects.
1593   addClassMethSummary("NSPanel", "alloc", NoTrackYet);
1594 
1595   // For NSNull, objects returned by +null are singletons that ignore
1596   // retain/release semantics.  Just don't track them.
1597   // <rdar://problem/12858915>
1598   addClassMethSummary("NSNull", "null", NoTrackYet);
1599 
1600   // Don't track allocated autorelease pools, as it is okay to prematurely
1601   // exit a method.
1602   addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet);
1603   addClassMethSummary("NSAutoreleasePool", "allocWithZone", NoTrackYet, false);
1604   addClassMethSummary("NSAutoreleasePool", "new", NoTrackYet);
1605 
1606   // Create summaries QCRenderer/QCView -createSnapShotImageOfType:
1607   addInstMethSummary("QCRenderer", AllocSumm,
1608                      "createSnapshotImageOfType", nullptr);
1609   addInstMethSummary("QCView", AllocSumm,
1610                      "createSnapshotImageOfType", nullptr);
1611 
1612   // Create summaries for CIContext, 'createCGImage' and
1613   // 'createCGLayerWithSize'.  These objects are CF objects, and are not
1614   // automatically garbage collected.
1615   addInstMethSummary("CIContext", CFAllocSumm,
1616                      "createCGImage", "fromRect", nullptr);
1617   addInstMethSummary("CIContext", CFAllocSumm, "createCGImage", "fromRect",
1618                      "format", "colorSpace", nullptr);
1619   addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info",
1620                      nullptr);
1621 }
1622 
1623 //===----------------------------------------------------------------------===//
1624 // Error reporting.
1625 //===----------------------------------------------------------------------===//
1626 namespace {
1627   typedef llvm::DenseMap<const ExplodedNode *, const RetainSummary *>
1628     SummaryLogTy;
1629 
1630   //===-------------===//
1631   // Bug Descriptions. //
1632   //===-------------===//
1633 
1634   class CFRefBug : public BugType {
1635   protected:
CFRefBug(const CheckerBase * checker,StringRef name)1636     CFRefBug(const CheckerBase *checker, StringRef name)
1637         : BugType(checker, name, categories::MemoryCoreFoundationObjectiveC) {}
1638 
1639   public:
1640 
1641     // FIXME: Eventually remove.
1642     virtual const char *getDescription() const = 0;
1643 
isLeak() const1644     virtual bool isLeak() const { return false; }
1645   };
1646 
1647   class UseAfterRelease : public CFRefBug {
1648   public:
UseAfterRelease(const CheckerBase * checker)1649     UseAfterRelease(const CheckerBase *checker)
1650         : CFRefBug(checker, "Use-after-release") {}
1651 
getDescription() const1652     const char *getDescription() const override {
1653       return "Reference-counted object is used after it is released";
1654     }
1655   };
1656 
1657   class BadRelease : public CFRefBug {
1658   public:
BadRelease(const CheckerBase * checker)1659     BadRelease(const CheckerBase *checker) : CFRefBug(checker, "Bad release") {}
1660 
getDescription() const1661     const char *getDescription() const override {
1662       return "Incorrect decrement of the reference count of an object that is "
1663              "not owned at this point by the caller";
1664     }
1665   };
1666 
1667   class DeallocGC : public CFRefBug {
1668   public:
DeallocGC(const CheckerBase * checker)1669     DeallocGC(const CheckerBase *checker)
1670         : CFRefBug(checker, "-dealloc called while using garbage collection") {}
1671 
getDescription() const1672     const char *getDescription() const override {
1673       return "-dealloc called while using garbage collection";
1674     }
1675   };
1676 
1677   class DeallocNotOwned : public CFRefBug {
1678   public:
DeallocNotOwned(const CheckerBase * checker)1679     DeallocNotOwned(const CheckerBase *checker)
1680         : CFRefBug(checker, "-dealloc sent to non-exclusively owned object") {}
1681 
getDescription() const1682     const char *getDescription() const override {
1683       return "-dealloc sent to object that may be referenced elsewhere";
1684     }
1685   };
1686 
1687   class OverAutorelease : public CFRefBug {
1688   public:
OverAutorelease(const CheckerBase * checker)1689     OverAutorelease(const CheckerBase *checker)
1690         : CFRefBug(checker, "Object autoreleased too many times") {}
1691 
getDescription() const1692     const char *getDescription() const override {
1693       return "Object autoreleased too many times";
1694     }
1695   };
1696 
1697   class ReturnedNotOwnedForOwned : public CFRefBug {
1698   public:
ReturnedNotOwnedForOwned(const CheckerBase * checker)1699     ReturnedNotOwnedForOwned(const CheckerBase *checker)
1700         : CFRefBug(checker, "Method should return an owned object") {}
1701 
getDescription() const1702     const char *getDescription() const override {
1703       return "Object with a +0 retain count returned to caller where a +1 "
1704              "(owning) retain count is expected";
1705     }
1706   };
1707 
1708   class Leak : public CFRefBug {
1709   public:
Leak(const CheckerBase * checker,StringRef name)1710     Leak(const CheckerBase *checker, StringRef name) : CFRefBug(checker, name) {
1711       // Leaks should not be reported if they are post-dominated by a sink.
1712       setSuppressOnSink(true);
1713     }
1714 
getDescription() const1715     const char *getDescription() const override { return ""; }
1716 
isLeak() const1717     bool isLeak() const override { return true; }
1718   };
1719 
1720   //===---------===//
1721   // Bug Reports.  //
1722   //===---------===//
1723 
1724   class CFRefReportVisitor : public BugReporterVisitorImpl<CFRefReportVisitor> {
1725   protected:
1726     SymbolRef Sym;
1727     const SummaryLogTy &SummaryLog;
1728     bool GCEnabled;
1729 
1730   public:
CFRefReportVisitor(SymbolRef sym,bool gcEnabled,const SummaryLogTy & log)1731     CFRefReportVisitor(SymbolRef sym, bool gcEnabled, const SummaryLogTy &log)
1732        : Sym(sym), SummaryLog(log), GCEnabled(gcEnabled) {}
1733 
Profile(llvm::FoldingSetNodeID & ID) const1734     void Profile(llvm::FoldingSetNodeID &ID) const override {
1735       static int x = 0;
1736       ID.AddPointer(&x);
1737       ID.AddPointer(Sym);
1738     }
1739 
1740     PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
1741                                    const ExplodedNode *PrevN,
1742                                    BugReporterContext &BRC,
1743                                    BugReport &BR) override;
1744 
1745     std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
1746                                                     const ExplodedNode *N,
1747                                                     BugReport &BR) override;
1748   };
1749 
1750   class CFRefLeakReportVisitor : public CFRefReportVisitor {
1751   public:
CFRefLeakReportVisitor(SymbolRef sym,bool GCEnabled,const SummaryLogTy & log)1752     CFRefLeakReportVisitor(SymbolRef sym, bool GCEnabled,
1753                            const SummaryLogTy &log)
1754        : CFRefReportVisitor(sym, GCEnabled, log) {}
1755 
1756     std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
1757                                                     const ExplodedNode *N,
1758                                                     BugReport &BR) override;
1759 
clone() const1760     std::unique_ptr<BugReporterVisitor> clone() const override {
1761       // The curiously-recurring template pattern only works for one level of
1762       // subclassing. Rather than make a new template base for
1763       // CFRefReportVisitor, we simply override clone() to do the right thing.
1764       // This could be trouble someday if BugReporterVisitorImpl is ever
1765       // used for something else besides a convenient implementation of clone().
1766       return llvm::make_unique<CFRefLeakReportVisitor>(*this);
1767     }
1768   };
1769 
1770   class CFRefReport : public BugReport {
1771     void addGCModeDescription(const LangOptions &LOpts, bool GCEnabled);
1772 
1773   public:
CFRefReport(CFRefBug & D,const LangOptions & LOpts,bool GCEnabled,const SummaryLogTy & Log,ExplodedNode * n,SymbolRef sym,bool registerVisitor=true)1774     CFRefReport(CFRefBug &D, const LangOptions &LOpts, bool GCEnabled,
1775                 const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
1776                 bool registerVisitor = true)
1777       : BugReport(D, D.getDescription(), n) {
1778       if (registerVisitor)
1779         addVisitor(llvm::make_unique<CFRefReportVisitor>(sym, GCEnabled, Log));
1780       addGCModeDescription(LOpts, GCEnabled);
1781     }
1782 
CFRefReport(CFRefBug & D,const LangOptions & LOpts,bool GCEnabled,const SummaryLogTy & Log,ExplodedNode * n,SymbolRef sym,StringRef endText)1783     CFRefReport(CFRefBug &D, const LangOptions &LOpts, bool GCEnabled,
1784                 const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
1785                 StringRef endText)
1786       : BugReport(D, D.getDescription(), endText, n) {
1787       addVisitor(llvm::make_unique<CFRefReportVisitor>(sym, GCEnabled, Log));
1788       addGCModeDescription(LOpts, GCEnabled);
1789     }
1790 
getRanges()1791     llvm::iterator_range<ranges_iterator> getRanges() override {
1792       const CFRefBug& BugTy = static_cast<CFRefBug&>(getBugType());
1793       if (!BugTy.isLeak())
1794         return BugReport::getRanges();
1795       return llvm::make_range(ranges_iterator(), ranges_iterator());
1796     }
1797   };
1798 
1799   class CFRefLeakReport : public CFRefReport {
1800     const MemRegion* AllocBinding;
1801   public:
1802     CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts, bool GCEnabled,
1803                     const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
1804                     CheckerContext &Ctx,
1805                     bool IncludeAllocationLine);
1806 
getLocation(const SourceManager & SM) const1807     PathDiagnosticLocation getLocation(const SourceManager &SM) const override {
1808       assert(Location.isValid());
1809       return Location;
1810     }
1811   };
1812 } // end anonymous namespace
1813 
addGCModeDescription(const LangOptions & LOpts,bool GCEnabled)1814 void CFRefReport::addGCModeDescription(const LangOptions &LOpts,
1815                                        bool GCEnabled) {
1816   const char *GCModeDescription = nullptr;
1817 
1818   switch (LOpts.getGC()) {
1819   case LangOptions::GCOnly:
1820     assert(GCEnabled);
1821     GCModeDescription = "Code is compiled to only use garbage collection";
1822     break;
1823 
1824   case LangOptions::NonGC:
1825     assert(!GCEnabled);
1826     GCModeDescription = "Code is compiled to use reference counts";
1827     break;
1828 
1829   case LangOptions::HybridGC:
1830     if (GCEnabled) {
1831       GCModeDescription = "Code is compiled to use either garbage collection "
1832                           "(GC) or reference counts (non-GC).  The bug occurs "
1833                           "with GC enabled";
1834       break;
1835     } else {
1836       GCModeDescription = "Code is compiled to use either garbage collection "
1837                           "(GC) or reference counts (non-GC).  The bug occurs "
1838                           "in non-GC mode";
1839       break;
1840     }
1841   }
1842 
1843   assert(GCModeDescription && "invalid/unknown GC mode");
1844   addExtraText(GCModeDescription);
1845 }
1846 
isNumericLiteralExpression(const Expr * E)1847 static bool isNumericLiteralExpression(const Expr *E) {
1848   // FIXME: This set of cases was copied from SemaExprObjC.
1849   return isa<IntegerLiteral>(E) ||
1850          isa<CharacterLiteral>(E) ||
1851          isa<FloatingLiteral>(E) ||
1852          isa<ObjCBoolLiteralExpr>(E) ||
1853          isa<CXXBoolLiteralExpr>(E);
1854 }
1855 
1856 /// Returns true if this stack frame is for an Objective-C method that is a
1857 /// property getter or setter whose body has been synthesized by the analyzer.
isSynthesizedAccessor(const StackFrameContext * SFC)1858 static bool isSynthesizedAccessor(const StackFrameContext *SFC) {
1859   auto Method = dyn_cast_or_null<ObjCMethodDecl>(SFC->getDecl());
1860   if (!Method || !Method->isPropertyAccessor())
1861     return false;
1862 
1863   return SFC->getAnalysisDeclContext()->isBodyAutosynthesized();
1864 }
1865 
VisitNode(const ExplodedNode * N,const ExplodedNode * PrevN,BugReporterContext & BRC,BugReport & BR)1866 PathDiagnosticPiece *CFRefReportVisitor::VisitNode(const ExplodedNode *N,
1867                                                    const ExplodedNode *PrevN,
1868                                                    BugReporterContext &BRC,
1869                                                    BugReport &BR) {
1870   // FIXME: We will eventually need to handle non-statement-based events
1871   // (__attribute__((cleanup))).
1872   if (!N->getLocation().getAs<StmtPoint>())
1873     return nullptr;
1874 
1875   // Check if the type state has changed.
1876   ProgramStateRef PrevSt = PrevN->getState();
1877   ProgramStateRef CurrSt = N->getState();
1878   const LocationContext *LCtx = N->getLocationContext();
1879 
1880   const RefVal* CurrT = getRefBinding(CurrSt, Sym);
1881   if (!CurrT) return nullptr;
1882 
1883   const RefVal &CurrV = *CurrT;
1884   const RefVal *PrevT = getRefBinding(PrevSt, Sym);
1885 
1886   // Create a string buffer to constain all the useful things we want
1887   // to tell the user.
1888   std::string sbuf;
1889   llvm::raw_string_ostream os(sbuf);
1890 
1891   // This is the allocation site since the previous node had no bindings
1892   // for this symbol.
1893   if (!PrevT) {
1894     const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
1895 
1896     if (isa<ObjCIvarRefExpr>(S) &&
1897         isSynthesizedAccessor(LCtx->getCurrentStackFrame())) {
1898       S = LCtx->getCurrentStackFrame()->getCallSite();
1899     }
1900 
1901     if (isa<ObjCArrayLiteral>(S)) {
1902       os << "NSArray literal is an object with a +0 retain count";
1903     }
1904     else if (isa<ObjCDictionaryLiteral>(S)) {
1905       os << "NSDictionary literal is an object with a +0 retain count";
1906     }
1907     else if (const ObjCBoxedExpr *BL = dyn_cast<ObjCBoxedExpr>(S)) {
1908       if (isNumericLiteralExpression(BL->getSubExpr()))
1909         os << "NSNumber literal is an object with a +0 retain count";
1910       else {
1911         const ObjCInterfaceDecl *BoxClass = nullptr;
1912         if (const ObjCMethodDecl *Method = BL->getBoxingMethod())
1913           BoxClass = Method->getClassInterface();
1914 
1915         // We should always be able to find the boxing class interface,
1916         // but consider this future-proofing.
1917         if (BoxClass)
1918           os << *BoxClass << " b";
1919         else
1920           os << "B";
1921 
1922         os << "oxed expression produces an object with a +0 retain count";
1923       }
1924     }
1925     else if (isa<ObjCIvarRefExpr>(S)) {
1926       os << "Object loaded from instance variable";
1927     }
1928     else {
1929       if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
1930         // Get the name of the callee (if it is available).
1931         SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee(), LCtx);
1932         if (const FunctionDecl *FD = X.getAsFunctionDecl())
1933           os << "Call to function '" << *FD << '\'';
1934         else
1935           os << "function call";
1936       }
1937       else {
1938         assert(isa<ObjCMessageExpr>(S));
1939         CallEventManager &Mgr = CurrSt->getStateManager().getCallEventManager();
1940         CallEventRef<ObjCMethodCall> Call
1941           = Mgr.getObjCMethodCall(cast<ObjCMessageExpr>(S), CurrSt, LCtx);
1942 
1943         switch (Call->getMessageKind()) {
1944         case OCM_Message:
1945           os << "Method";
1946           break;
1947         case OCM_PropertyAccess:
1948           os << "Property";
1949           break;
1950         case OCM_Subscript:
1951           os << "Subscript";
1952           break;
1953         }
1954       }
1955 
1956       if (CurrV.getObjKind() == RetEffect::CF) {
1957         os << " returns a Core Foundation object with a ";
1958       }
1959       else {
1960         assert (CurrV.getObjKind() == RetEffect::ObjC);
1961         os << " returns an Objective-C object with a ";
1962       }
1963 
1964       if (CurrV.isOwned()) {
1965         os << "+1 retain count";
1966 
1967         if (GCEnabled) {
1968           assert(CurrV.getObjKind() == RetEffect::CF);
1969           os << ".  "
1970           "Core Foundation objects are not automatically garbage collected.";
1971         }
1972       }
1973       else {
1974         assert (CurrV.isNotOwned());
1975         os << "+0 retain count";
1976       }
1977     }
1978 
1979     PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
1980                                   N->getLocationContext());
1981     return new PathDiagnosticEventPiece(Pos, os.str());
1982   }
1983 
1984   // Gather up the effects that were performed on the object at this
1985   // program point
1986   SmallVector<ArgEffect, 2> AEffects;
1987 
1988   const ExplodedNode *OrigNode = BRC.getNodeResolver().getOriginalNode(N);
1989   if (const RetainSummary *Summ = SummaryLog.lookup(OrigNode)) {
1990     // We only have summaries attached to nodes after evaluating CallExpr and
1991     // ObjCMessageExprs.
1992     const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
1993 
1994     if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
1995       // Iterate through the parameter expressions and see if the symbol
1996       // was ever passed as an argument.
1997       unsigned i = 0;
1998 
1999       for (CallExpr::const_arg_iterator AI=CE->arg_begin(), AE=CE->arg_end();
2000            AI!=AE; ++AI, ++i) {
2001 
2002         // Retrieve the value of the argument.  Is it the symbol
2003         // we are interested in?
2004         if (CurrSt->getSValAsScalarOrLoc(*AI, LCtx).getAsLocSymbol() != Sym)
2005           continue;
2006 
2007         // We have an argument.  Get the effect!
2008         AEffects.push_back(Summ->getArg(i));
2009       }
2010     }
2011     else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {
2012       if (const Expr *receiver = ME->getInstanceReceiver())
2013         if (CurrSt->getSValAsScalarOrLoc(receiver, LCtx)
2014               .getAsLocSymbol() == Sym) {
2015           // The symbol we are tracking is the receiver.
2016           AEffects.push_back(Summ->getReceiverEffect());
2017         }
2018     }
2019   }
2020 
2021   do {
2022     // Get the previous type state.
2023     RefVal PrevV = *PrevT;
2024 
2025     // Specially handle -dealloc.
2026     if (!GCEnabled && std::find(AEffects.begin(), AEffects.end(), Dealloc) !=
2027                           AEffects.end()) {
2028       // Determine if the object's reference count was pushed to zero.
2029       assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
2030       // We may not have transitioned to 'release' if we hit an error.
2031       // This case is handled elsewhere.
2032       if (CurrV.getKind() == RefVal::Released) {
2033         assert(CurrV.getCombinedCounts() == 0);
2034         os << "Object released by directly sending the '-dealloc' message";
2035         break;
2036       }
2037     }
2038 
2039     // Specially handle CFMakeCollectable and friends.
2040     if (std::find(AEffects.begin(), AEffects.end(), MakeCollectable) !=
2041         AEffects.end()) {
2042       // Get the name of the function.
2043       const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
2044       SVal X =
2045         CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee(), LCtx);
2046       const FunctionDecl *FD = X.getAsFunctionDecl();
2047 
2048       if (GCEnabled) {
2049         // Determine if the object's reference count was pushed to zero.
2050         assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
2051 
2052         os << "In GC mode a call to '" << *FD
2053         <<  "' decrements an object's retain count and registers the "
2054         "object with the garbage collector. ";
2055 
2056         if (CurrV.getKind() == RefVal::Released) {
2057           assert(CurrV.getCount() == 0);
2058           os << "Since it now has a 0 retain count the object can be "
2059           "automatically collected by the garbage collector.";
2060         }
2061         else
2062           os << "An object must have a 0 retain count to be garbage collected. "
2063           "After this call its retain count is +" << CurrV.getCount()
2064           << '.';
2065       }
2066       else
2067         os << "When GC is not enabled a call to '" << *FD
2068         << "' has no effect on its argument.";
2069 
2070       // Nothing more to say.
2071       break;
2072     }
2073 
2074     // Determine if the typestate has changed.
2075     if (!PrevV.hasSameState(CurrV))
2076       switch (CurrV.getKind()) {
2077         case RefVal::Owned:
2078         case RefVal::NotOwned:
2079           if (PrevV.getCount() == CurrV.getCount()) {
2080             // Did an autorelease message get sent?
2081             if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount())
2082               return nullptr;
2083 
2084             assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());
2085             os << "Object autoreleased";
2086             break;
2087           }
2088 
2089           if (PrevV.getCount() > CurrV.getCount())
2090             os << "Reference count decremented.";
2091           else
2092             os << "Reference count incremented.";
2093 
2094           if (unsigned Count = CurrV.getCount())
2095             os << " The object now has a +" << Count << " retain count.";
2096 
2097           if (PrevV.getKind() == RefVal::Released) {
2098             assert(GCEnabled && CurrV.getCount() > 0);
2099             os << " The object is not eligible for garbage collection until "
2100                   "the retain count reaches 0 again.";
2101           }
2102 
2103           break;
2104 
2105         case RefVal::Released:
2106           if (CurrV.getIvarAccessHistory() ==
2107                 RefVal::IvarAccessHistory::ReleasedAfterDirectAccess &&
2108               CurrV.getIvarAccessHistory() != PrevV.getIvarAccessHistory()) {
2109             os << "Strong instance variable relinquished. ";
2110           }
2111           os << "Object released.";
2112           break;
2113 
2114         case RefVal::ReturnedOwned:
2115           // Autoreleases can be applied after marking a node ReturnedOwned.
2116           if (CurrV.getAutoreleaseCount())
2117             return nullptr;
2118 
2119           os << "Object returned to caller as an owning reference (single "
2120                 "retain count transferred to caller)";
2121           break;
2122 
2123         case RefVal::ReturnedNotOwned:
2124           os << "Object returned to caller with a +0 retain count";
2125           break;
2126 
2127         default:
2128           return nullptr;
2129       }
2130 
2131     // Emit any remaining diagnostics for the argument effects (if any).
2132     for (SmallVectorImpl<ArgEffect>::iterator I=AEffects.begin(),
2133          E=AEffects.end(); I != E; ++I) {
2134 
2135       // A bunch of things have alternate behavior under GC.
2136       if (GCEnabled)
2137         switch (*I) {
2138           default: break;
2139           case Autorelease:
2140             os << "In GC mode an 'autorelease' has no effect.";
2141             continue;
2142           case IncRefMsg:
2143             os << "In GC mode the 'retain' message has no effect.";
2144             continue;
2145           case DecRefMsg:
2146             os << "In GC mode the 'release' message has no effect.";
2147             continue;
2148         }
2149     }
2150   } while (0);
2151 
2152   if (os.str().empty())
2153     return nullptr; // We have nothing to say!
2154 
2155   const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
2156   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
2157                                 N->getLocationContext());
2158   PathDiagnosticPiece *P = new PathDiagnosticEventPiece(Pos, os.str());
2159 
2160   // Add the range by scanning the children of the statement for any bindings
2161   // to Sym.
2162   for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
2163        I!=E; ++I)
2164     if (const Expr *Exp = dyn_cast_or_null<Expr>(*I))
2165       if (CurrSt->getSValAsScalarOrLoc(Exp, LCtx).getAsLocSymbol() == Sym) {
2166         P->addRange(Exp->getSourceRange());
2167         break;
2168       }
2169 
2170   return P;
2171 }
2172 
2173 // Find the first node in the current function context that referred to the
2174 // tracked symbol and the memory location that value was stored to. Note, the
2175 // value is only reported if the allocation occurred in the same function as
2176 // the leak. The function can also return a location context, which should be
2177 // treated as interesting.
2178 struct AllocationInfo {
2179   const ExplodedNode* N;
2180   const MemRegion *R;
2181   const LocationContext *InterestingMethodContext;
AllocationInfoAllocationInfo2182   AllocationInfo(const ExplodedNode *InN,
2183                  const MemRegion *InR,
2184                  const LocationContext *InInterestingMethodContext) :
2185     N(InN), R(InR), InterestingMethodContext(InInterestingMethodContext) {}
2186 };
2187 
2188 static AllocationInfo
GetAllocationSite(ProgramStateManager & StateMgr,const ExplodedNode * N,SymbolRef Sym)2189 GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
2190                   SymbolRef Sym) {
2191   const ExplodedNode *AllocationNode = N;
2192   const ExplodedNode *AllocationNodeInCurrentOrParentContext = N;
2193   const MemRegion *FirstBinding = nullptr;
2194   const LocationContext *LeakContext = N->getLocationContext();
2195 
2196   // The location context of the init method called on the leaked object, if
2197   // available.
2198   const LocationContext *InitMethodContext = nullptr;
2199 
2200   while (N) {
2201     ProgramStateRef St = N->getState();
2202     const LocationContext *NContext = N->getLocationContext();
2203 
2204     if (!getRefBinding(St, Sym))
2205       break;
2206 
2207     StoreManager::FindUniqueBinding FB(Sym);
2208     StateMgr.iterBindings(St, FB);
2209 
2210     if (FB) {
2211       const MemRegion *R = FB.getRegion();
2212       const VarRegion *VR = R->getBaseRegion()->getAs<VarRegion>();
2213       // Do not show local variables belonging to a function other than
2214       // where the error is reported.
2215       if (!VR || VR->getStackFrame() == LeakContext->getCurrentStackFrame())
2216         FirstBinding = R;
2217     }
2218 
2219     // AllocationNode is the last node in which the symbol was tracked.
2220     AllocationNode = N;
2221 
2222     // AllocationNodeInCurrentContext, is the last node in the current or
2223     // parent context in which the symbol was tracked.
2224     //
2225     // Note that the allocation site might be in the parent conext. For example,
2226     // the case where an allocation happens in a block that captures a reference
2227     // to it and that reference is overwritten/dropped by another call to
2228     // the block.
2229     if (NContext == LeakContext || NContext->isParentOf(LeakContext))
2230       AllocationNodeInCurrentOrParentContext = N;
2231 
2232     // Find the last init that was called on the given symbol and store the
2233     // init method's location context.
2234     if (!InitMethodContext)
2235       if (Optional<CallEnter> CEP = N->getLocation().getAs<CallEnter>()) {
2236         const Stmt *CE = CEP->getCallExpr();
2237         if (const ObjCMessageExpr *ME = dyn_cast_or_null<ObjCMessageExpr>(CE)) {
2238           const Stmt *RecExpr = ME->getInstanceReceiver();
2239           if (RecExpr) {
2240             SVal RecV = St->getSVal(RecExpr, NContext);
2241             if (ME->getMethodFamily() == OMF_init && RecV.getAsSymbol() == Sym)
2242               InitMethodContext = CEP->getCalleeContext();
2243           }
2244         }
2245       }
2246 
2247     N = N->pred_empty() ? nullptr : *(N->pred_begin());
2248   }
2249 
2250   // If we are reporting a leak of the object that was allocated with alloc,
2251   // mark its init method as interesting.
2252   const LocationContext *InterestingMethodContext = nullptr;
2253   if (InitMethodContext) {
2254     const ProgramPoint AllocPP = AllocationNode->getLocation();
2255     if (Optional<StmtPoint> SP = AllocPP.getAs<StmtPoint>())
2256       if (const ObjCMessageExpr *ME = SP->getStmtAs<ObjCMessageExpr>())
2257         if (ME->getMethodFamily() == OMF_alloc)
2258           InterestingMethodContext = InitMethodContext;
2259   }
2260 
2261   // If allocation happened in a function different from the leak node context,
2262   // do not report the binding.
2263   assert(N && "Could not find allocation node");
2264   if (N->getLocationContext() != LeakContext) {
2265     FirstBinding = nullptr;
2266   }
2267 
2268   return AllocationInfo(AllocationNodeInCurrentOrParentContext,
2269                         FirstBinding,
2270                         InterestingMethodContext);
2271 }
2272 
2273 std::unique_ptr<PathDiagnosticPiece>
getEndPath(BugReporterContext & BRC,const ExplodedNode * EndN,BugReport & BR)2274 CFRefReportVisitor::getEndPath(BugReporterContext &BRC,
2275                                const ExplodedNode *EndN, BugReport &BR) {
2276   BR.markInteresting(Sym);
2277   return BugReporterVisitor::getDefaultEndPath(BRC, EndN, BR);
2278 }
2279 
2280 std::unique_ptr<PathDiagnosticPiece>
getEndPath(BugReporterContext & BRC,const ExplodedNode * EndN,BugReport & BR)2281 CFRefLeakReportVisitor::getEndPath(BugReporterContext &BRC,
2282                                    const ExplodedNode *EndN, BugReport &BR) {
2283 
2284   // Tell the BugReporterContext to report cases when the tracked symbol is
2285   // assigned to different variables, etc.
2286   BR.markInteresting(Sym);
2287 
2288   // We are reporting a leak.  Walk up the graph to get to the first node where
2289   // the symbol appeared, and also get the first VarDecl that tracked object
2290   // is stored to.
2291   AllocationInfo AllocI =
2292     GetAllocationSite(BRC.getStateManager(), EndN, Sym);
2293 
2294   const MemRegion* FirstBinding = AllocI.R;
2295   BR.markInteresting(AllocI.InterestingMethodContext);
2296 
2297   SourceManager& SM = BRC.getSourceManager();
2298 
2299   // Compute an actual location for the leak.  Sometimes a leak doesn't
2300   // occur at an actual statement (e.g., transition between blocks; end
2301   // of function) so we need to walk the graph and compute a real location.
2302   const ExplodedNode *LeakN = EndN;
2303   PathDiagnosticLocation L = PathDiagnosticLocation::createEndOfPath(LeakN, SM);
2304 
2305   std::string sbuf;
2306   llvm::raw_string_ostream os(sbuf);
2307 
2308   os << "Object leaked: ";
2309 
2310   if (FirstBinding) {
2311     os << "object allocated and stored into '"
2312        << FirstBinding->getString() << '\'';
2313   }
2314   else
2315     os << "allocated object";
2316 
2317   // Get the retain count.
2318   const RefVal* RV = getRefBinding(EndN->getState(), Sym);
2319   assert(RV);
2320 
2321   if (RV->getKind() == RefVal::ErrorLeakReturned) {
2322     // FIXME: Per comments in rdar://6320065, "create" only applies to CF
2323     // objects.  Only "copy", "alloc", "retain" and "new" transfer ownership
2324     // to the caller for NS objects.
2325     const Decl *D = &EndN->getCodeDecl();
2326 
2327     os << (isa<ObjCMethodDecl>(D) ? " is returned from a method "
2328                                   : " is returned from a function ");
2329 
2330     if (D->hasAttr<CFReturnsNotRetainedAttr>())
2331       os << "that is annotated as CF_RETURNS_NOT_RETAINED";
2332     else if (D->hasAttr<NSReturnsNotRetainedAttr>())
2333       os << "that is annotated as NS_RETURNS_NOT_RETAINED";
2334     else {
2335       if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
2336         os << "whose name ('" << MD->getSelector().getAsString()
2337            << "') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'."
2338               "  This violates the naming convention rules"
2339               " given in the Memory Management Guide for Cocoa";
2340       }
2341       else {
2342         const FunctionDecl *FD = cast<FunctionDecl>(D);
2343         os << "whose name ('" << *FD
2344            << "') does not contain 'Copy' or 'Create'.  This violates the naming"
2345               " convention rules given in the Memory Management Guide for Core"
2346               " Foundation";
2347       }
2348     }
2349   }
2350   else if (RV->getKind() == RefVal::ErrorGCLeakReturned) {
2351     const ObjCMethodDecl &MD = cast<ObjCMethodDecl>(EndN->getCodeDecl());
2352     os << " and returned from method '" << MD.getSelector().getAsString()
2353        << "' is potentially leaked when using garbage collection.  Callers "
2354           "of this method do not expect a returned object with a +1 retain "
2355           "count since they expect the object to be managed by the garbage "
2356           "collector";
2357   }
2358   else
2359     os << " is not referenced later in this execution path and has a retain "
2360           "count of +" << RV->getCount();
2361 
2362   return llvm::make_unique<PathDiagnosticEventPiece>(L, os.str());
2363 }
2364 
CFRefLeakReport(CFRefBug & D,const LangOptions & LOpts,bool GCEnabled,const SummaryLogTy & Log,ExplodedNode * n,SymbolRef sym,CheckerContext & Ctx,bool IncludeAllocationLine)2365 CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
2366                                  bool GCEnabled, const SummaryLogTy &Log,
2367                                  ExplodedNode *n, SymbolRef sym,
2368                                  CheckerContext &Ctx,
2369                                  bool IncludeAllocationLine)
2370   : CFRefReport(D, LOpts, GCEnabled, Log, n, sym, false) {
2371 
2372   // Most bug reports are cached at the location where they occurred.
2373   // With leaks, we want to unique them by the location where they were
2374   // allocated, and only report a single path.  To do this, we need to find
2375   // the allocation site of a piece of tracked memory, which we do via a
2376   // call to GetAllocationSite.  This will walk the ExplodedGraph backwards.
2377   // Note that this is *not* the trimmed graph; we are guaranteed, however,
2378   // that all ancestor nodes that represent the allocation site have the
2379   // same SourceLocation.
2380   const ExplodedNode *AllocNode = nullptr;
2381 
2382   const SourceManager& SMgr = Ctx.getSourceManager();
2383 
2384   AllocationInfo AllocI =
2385     GetAllocationSite(Ctx.getStateManager(), getErrorNode(), sym);
2386 
2387   AllocNode = AllocI.N;
2388   AllocBinding = AllocI.R;
2389   markInteresting(AllocI.InterestingMethodContext);
2390 
2391   // Get the SourceLocation for the allocation site.
2392   // FIXME: This will crash the analyzer if an allocation comes from an
2393   // implicit call (ex: a destructor call).
2394   // (Currently there are no such allocations in Cocoa, though.)
2395   const Stmt *AllocStmt = 0;
2396   ProgramPoint P = AllocNode->getLocation();
2397   if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
2398     AllocStmt = Exit->getCalleeContext()->getCallSite();
2399   else
2400     AllocStmt = P.castAs<PostStmt>().getStmt();
2401   assert(AllocStmt && "Cannot find allocation statement");
2402 
2403   PathDiagnosticLocation AllocLocation =
2404     PathDiagnosticLocation::createBegin(AllocStmt, SMgr,
2405                                         AllocNode->getLocationContext());
2406   Location = AllocLocation;
2407 
2408   // Set uniqieing info, which will be used for unique the bug reports. The
2409   // leaks should be uniqued on the allocation site.
2410   UniqueingLocation = AllocLocation;
2411   UniqueingDecl = AllocNode->getLocationContext()->getDecl();
2412 
2413   // Fill in the description of the bug.
2414   Description.clear();
2415   llvm::raw_string_ostream os(Description);
2416   os << "Potential leak ";
2417   if (GCEnabled)
2418     os << "(when using garbage collection) ";
2419   os << "of an object";
2420 
2421   if (AllocBinding) {
2422     os << " stored into '" << AllocBinding->getString() << '\'';
2423     if (IncludeAllocationLine) {
2424       FullSourceLoc SL(AllocStmt->getLocStart(), Ctx.getSourceManager());
2425       os << " (allocated on line " << SL.getSpellingLineNumber() << ")";
2426     }
2427   }
2428 
2429   addVisitor(llvm::make_unique<CFRefLeakReportVisitor>(sym, GCEnabled, Log));
2430 }
2431 
2432 //===----------------------------------------------------------------------===//
2433 // Main checker logic.
2434 //===----------------------------------------------------------------------===//
2435 
2436 namespace {
2437 class RetainCountChecker
2438   : public Checker< check::Bind,
2439                     check::DeadSymbols,
2440                     check::EndAnalysis,
2441                     check::EndFunction,
2442                     check::PostStmt<BlockExpr>,
2443                     check::PostStmt<CastExpr>,
2444                     check::PostStmt<ObjCArrayLiteral>,
2445                     check::PostStmt<ObjCDictionaryLiteral>,
2446                     check::PostStmt<ObjCBoxedExpr>,
2447                     check::PostStmt<ObjCIvarRefExpr>,
2448                     check::PostCall,
2449                     check::PreStmt<ReturnStmt>,
2450                     check::RegionChanges,
2451                     eval::Assume,
2452                     eval::Call > {
2453   mutable std::unique_ptr<CFRefBug> useAfterRelease, releaseNotOwned;
2454   mutable std::unique_ptr<CFRefBug> deallocGC, deallocNotOwned;
2455   mutable std::unique_ptr<CFRefBug> overAutorelease, returnNotOwnedForOwned;
2456   mutable std::unique_ptr<CFRefBug> leakWithinFunction, leakAtReturn;
2457   mutable std::unique_ptr<CFRefBug> leakWithinFunctionGC, leakAtReturnGC;
2458 
2459   typedef llvm::DenseMap<SymbolRef, const CheckerProgramPointTag *> SymbolTagMap;
2460 
2461   // This map is only used to ensure proper deletion of any allocated tags.
2462   mutable SymbolTagMap DeadSymbolTags;
2463 
2464   mutable std::unique_ptr<RetainSummaryManager> Summaries;
2465   mutable std::unique_ptr<RetainSummaryManager> SummariesGC;
2466   mutable SummaryLogTy SummaryLog;
2467   mutable bool ShouldResetSummaryLog;
2468 
2469   /// Optional setting to indicate if leak reports should include
2470   /// the allocation line.
2471   mutable bool IncludeAllocationLine;
2472 
2473 public:
RetainCountChecker(AnalyzerOptions & AO)2474   RetainCountChecker(AnalyzerOptions &AO)
2475     : ShouldResetSummaryLog(false),
2476       IncludeAllocationLine(shouldIncludeAllocationSiteInLeakDiagnostics(AO)) {}
2477 
~RetainCountChecker()2478   ~RetainCountChecker() override { DeleteContainerSeconds(DeadSymbolTags); }
2479 
checkEndAnalysis(ExplodedGraph & G,BugReporter & BR,ExprEngine & Eng) const2480   void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR,
2481                         ExprEngine &Eng) const {
2482     // FIXME: This is a hack to make sure the summary log gets cleared between
2483     // analyses of different code bodies.
2484     //
2485     // Why is this necessary? Because a checker's lifetime is tied to a
2486     // translation unit, but an ExplodedGraph's lifetime is just a code body.
2487     // Once in a blue moon, a new ExplodedNode will have the same address as an
2488     // old one with an associated summary, and the bug report visitor gets very
2489     // confused. (To make things worse, the summary lifetime is currently also
2490     // tied to a code body, so we get a crash instead of incorrect results.)
2491     //
2492     // Why is this a bad solution? Because if the lifetime of the ExplodedGraph
2493     // changes, things will start going wrong again. Really the lifetime of this
2494     // log needs to be tied to either the specific nodes in it or the entire
2495     // ExplodedGraph, not to a specific part of the code being analyzed.
2496     //
2497     // (Also, having stateful local data means that the same checker can't be
2498     // used from multiple threads, but a lot of checkers have incorrect
2499     // assumptions about that anyway. So that wasn't a priority at the time of
2500     // this fix.)
2501     //
2502     // This happens at the end of analysis, but bug reports are emitted /after/
2503     // this point. So we can't just clear the summary log now. Instead, we mark
2504     // that the next time we access the summary log, it should be cleared.
2505 
2506     // If we never reset the summary log during /this/ code body analysis,
2507     // there were no new summaries. There might still have been summaries from
2508     // the /last/ analysis, so clear them out to make sure the bug report
2509     // visitors don't get confused.
2510     if (ShouldResetSummaryLog)
2511       SummaryLog.clear();
2512 
2513     ShouldResetSummaryLog = !SummaryLog.empty();
2514   }
2515 
getLeakWithinFunctionBug(const LangOptions & LOpts,bool GCEnabled) const2516   CFRefBug *getLeakWithinFunctionBug(const LangOptions &LOpts,
2517                                      bool GCEnabled) const {
2518     if (GCEnabled) {
2519       if (!leakWithinFunctionGC)
2520         leakWithinFunctionGC.reset(new Leak(this, "Leak of object when using "
2521                                                   "garbage collection"));
2522       return leakWithinFunctionGC.get();
2523     } else {
2524       if (!leakWithinFunction) {
2525         if (LOpts.getGC() == LangOptions::HybridGC) {
2526           leakWithinFunction.reset(new Leak(this,
2527                                             "Leak of object when not using "
2528                                             "garbage collection (GC) in "
2529                                             "dual GC/non-GC code"));
2530         } else {
2531           leakWithinFunction.reset(new Leak(this, "Leak"));
2532         }
2533       }
2534       return leakWithinFunction.get();
2535     }
2536   }
2537 
getLeakAtReturnBug(const LangOptions & LOpts,bool GCEnabled) const2538   CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts, bool GCEnabled) const {
2539     if (GCEnabled) {
2540       if (!leakAtReturnGC)
2541         leakAtReturnGC.reset(new Leak(this,
2542                                       "Leak of returned object when using "
2543                                       "garbage collection"));
2544       return leakAtReturnGC.get();
2545     } else {
2546       if (!leakAtReturn) {
2547         if (LOpts.getGC() == LangOptions::HybridGC) {
2548           leakAtReturn.reset(new Leak(this,
2549                                       "Leak of returned object when not using "
2550                                       "garbage collection (GC) in dual "
2551                                       "GC/non-GC code"));
2552         } else {
2553           leakAtReturn.reset(new Leak(this, "Leak of returned object"));
2554         }
2555       }
2556       return leakAtReturn.get();
2557     }
2558   }
2559 
getSummaryManager(ASTContext & Ctx,bool GCEnabled) const2560   RetainSummaryManager &getSummaryManager(ASTContext &Ctx,
2561                                           bool GCEnabled) const {
2562     // FIXME: We don't support ARC being turned on and off during one analysis.
2563     // (nor, for that matter, do we support changing ASTContexts)
2564     bool ARCEnabled = (bool)Ctx.getLangOpts().ObjCAutoRefCount;
2565     if (GCEnabled) {
2566       if (!SummariesGC)
2567         SummariesGC.reset(new RetainSummaryManager(Ctx, true, ARCEnabled));
2568       else
2569         assert(SummariesGC->isARCEnabled() == ARCEnabled);
2570       return *SummariesGC;
2571     } else {
2572       if (!Summaries)
2573         Summaries.reset(new RetainSummaryManager(Ctx, false, ARCEnabled));
2574       else
2575         assert(Summaries->isARCEnabled() == ARCEnabled);
2576       return *Summaries;
2577     }
2578   }
2579 
getSummaryManager(CheckerContext & C) const2580   RetainSummaryManager &getSummaryManager(CheckerContext &C) const {
2581     return getSummaryManager(C.getASTContext(), C.isObjCGCEnabled());
2582   }
2583 
2584   void printState(raw_ostream &Out, ProgramStateRef State,
2585                   const char *NL, const char *Sep) const override;
2586 
2587   void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
2588   void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
2589   void checkPostStmt(const CastExpr *CE, CheckerContext &C) const;
2590 
2591   void checkPostStmt(const ObjCArrayLiteral *AL, CheckerContext &C) const;
2592   void checkPostStmt(const ObjCDictionaryLiteral *DL, CheckerContext &C) const;
2593   void checkPostStmt(const ObjCBoxedExpr *BE, CheckerContext &C) const;
2594 
2595   void checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const;
2596 
2597   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
2598 
2599   void checkSummary(const RetainSummary &Summ, const CallEvent &Call,
2600                     CheckerContext &C) const;
2601 
2602   void processSummaryOfInlined(const RetainSummary &Summ,
2603                                const CallEvent &Call,
2604                                CheckerContext &C) const;
2605 
2606   bool evalCall(const CallExpr *CE, CheckerContext &C) const;
2607 
2608   ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
2609                                  bool Assumption) const;
2610 
2611   ProgramStateRef
2612   checkRegionChanges(ProgramStateRef state,
2613                      const InvalidatedSymbols *invalidated,
2614                      ArrayRef<const MemRegion *> ExplicitRegions,
2615                      ArrayRef<const MemRegion *> Regions,
2616                      const CallEvent *Call) const;
2617 
wantsRegionChangeUpdate(ProgramStateRef state) const2618   bool wantsRegionChangeUpdate(ProgramStateRef state) const {
2619     return true;
2620   }
2621 
2622   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
2623   void checkReturnWithRetEffect(const ReturnStmt *S, CheckerContext &C,
2624                                 ExplodedNode *Pred, RetEffect RE, RefVal X,
2625                                 SymbolRef Sym, ProgramStateRef state) const;
2626 
2627   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
2628   void checkEndFunction(CheckerContext &C) const;
2629 
2630   ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym,
2631                                RefVal V, ArgEffect E, RefVal::Kind &hasErr,
2632                                CheckerContext &C) const;
2633 
2634   void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,
2635                            RefVal::Kind ErrorKind, SymbolRef Sym,
2636                            CheckerContext &C) const;
2637 
2638   void processObjCLiterals(CheckerContext &C, const Expr *Ex) const;
2639 
2640   const ProgramPointTag *getDeadSymbolTag(SymbolRef sym) const;
2641 
2642   ProgramStateRef handleSymbolDeath(ProgramStateRef state,
2643                                     SymbolRef sid, RefVal V,
2644                                     SmallVectorImpl<SymbolRef> &Leaked) const;
2645 
2646   ProgramStateRef
2647   handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred,
2648                           const ProgramPointTag *Tag, CheckerContext &Ctx,
2649                           SymbolRef Sym, RefVal V) const;
2650 
2651   ExplodedNode *processLeaks(ProgramStateRef state,
2652                              SmallVectorImpl<SymbolRef> &Leaked,
2653                              CheckerContext &Ctx,
2654                              ExplodedNode *Pred = nullptr) const;
2655 };
2656 } // end anonymous namespace
2657 
2658 namespace {
2659 class StopTrackingCallback : public SymbolVisitor {
2660   ProgramStateRef state;
2661 public:
StopTrackingCallback(ProgramStateRef st)2662   StopTrackingCallback(ProgramStateRef st) : state(st) {}
getState() const2663   ProgramStateRef getState() const { return state; }
2664 
VisitSymbol(SymbolRef sym)2665   bool VisitSymbol(SymbolRef sym) override {
2666     state = state->remove<RefBindings>(sym);
2667     return true;
2668   }
2669 };
2670 } // end anonymous namespace
2671 
2672 //===----------------------------------------------------------------------===//
2673 // Handle statements that may have an effect on refcounts.
2674 //===----------------------------------------------------------------------===//
2675 
checkPostStmt(const BlockExpr * BE,CheckerContext & C) const2676 void RetainCountChecker::checkPostStmt(const BlockExpr *BE,
2677                                        CheckerContext &C) const {
2678 
2679   // Scan the BlockDecRefExprs for any object the retain count checker
2680   // may be tracking.
2681   if (!BE->getBlockDecl()->hasCaptures())
2682     return;
2683 
2684   ProgramStateRef state = C.getState();
2685   const BlockDataRegion *R =
2686     cast<BlockDataRegion>(state->getSVal(BE,
2687                                          C.getLocationContext()).getAsRegion());
2688 
2689   BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
2690                                             E = R->referenced_vars_end();
2691 
2692   if (I == E)
2693     return;
2694 
2695   // FIXME: For now we invalidate the tracking of all symbols passed to blocks
2696   // via captured variables, even though captured variables result in a copy
2697   // and in implicit increment/decrement of a retain count.
2698   SmallVector<const MemRegion*, 10> Regions;
2699   const LocationContext *LC = C.getLocationContext();
2700   MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
2701 
2702   for ( ; I != E; ++I) {
2703     const VarRegion *VR = I.getCapturedRegion();
2704     if (VR->getSuperRegion() == R) {
2705       VR = MemMgr.getVarRegion(VR->getDecl(), LC);
2706     }
2707     Regions.push_back(VR);
2708   }
2709 
2710   state =
2711     state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
2712                                     Regions.data() + Regions.size()).getState();
2713   C.addTransition(state);
2714 }
2715 
checkPostStmt(const CastExpr * CE,CheckerContext & C) const2716 void RetainCountChecker::checkPostStmt(const CastExpr *CE,
2717                                        CheckerContext &C) const {
2718   const ObjCBridgedCastExpr *BE = dyn_cast<ObjCBridgedCastExpr>(CE);
2719   if (!BE)
2720     return;
2721 
2722   ArgEffect AE = IncRef;
2723 
2724   switch (BE->getBridgeKind()) {
2725     case clang::OBC_Bridge:
2726       // Do nothing.
2727       return;
2728     case clang::OBC_BridgeRetained:
2729       AE = IncRef;
2730       break;
2731     case clang::OBC_BridgeTransfer:
2732       AE = DecRefBridgedTransferred;
2733       break;
2734   }
2735 
2736   ProgramStateRef state = C.getState();
2737   SymbolRef Sym = state->getSVal(CE, C.getLocationContext()).getAsLocSymbol();
2738   if (!Sym)
2739     return;
2740   const RefVal* T = getRefBinding(state, Sym);
2741   if (!T)
2742     return;
2743 
2744   RefVal::Kind hasErr = (RefVal::Kind) 0;
2745   state = updateSymbol(state, Sym, *T, AE, hasErr, C);
2746 
2747   if (hasErr) {
2748     // FIXME: If we get an error during a bridge cast, should we report it?
2749     // Should we assert that there is no error?
2750     return;
2751   }
2752 
2753   C.addTransition(state);
2754 }
2755 
processObjCLiterals(CheckerContext & C,const Expr * Ex) const2756 void RetainCountChecker::processObjCLiterals(CheckerContext &C,
2757                                              const Expr *Ex) const {
2758   ProgramStateRef state = C.getState();
2759   const ExplodedNode *pred = C.getPredecessor();
2760   for (Stmt::const_child_iterator it = Ex->child_begin(), et = Ex->child_end() ;
2761        it != et ; ++it) {
2762     const Stmt *child = *it;
2763     SVal V = state->getSVal(child, pred->getLocationContext());
2764     if (SymbolRef sym = V.getAsSymbol())
2765       if (const RefVal* T = getRefBinding(state, sym)) {
2766         RefVal::Kind hasErr = (RefVal::Kind) 0;
2767         state = updateSymbol(state, sym, *T, MayEscape, hasErr, C);
2768         if (hasErr) {
2769           processNonLeakError(state, child->getSourceRange(), hasErr, sym, C);
2770           return;
2771         }
2772       }
2773   }
2774 
2775   // Return the object as autoreleased.
2776   //  RetEffect RE = RetEffect::MakeNotOwned(RetEffect::ObjC);
2777   if (SymbolRef sym =
2778         state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
2779     QualType ResultTy = Ex->getType();
2780     state = setRefBinding(state, sym,
2781                           RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
2782   }
2783 
2784   C.addTransition(state);
2785 }
2786 
checkPostStmt(const ObjCArrayLiteral * AL,CheckerContext & C) const2787 void RetainCountChecker::checkPostStmt(const ObjCArrayLiteral *AL,
2788                                        CheckerContext &C) const {
2789   // Apply the 'MayEscape' to all values.
2790   processObjCLiterals(C, AL);
2791 }
2792 
checkPostStmt(const ObjCDictionaryLiteral * DL,CheckerContext & C) const2793 void RetainCountChecker::checkPostStmt(const ObjCDictionaryLiteral *DL,
2794                                        CheckerContext &C) const {
2795   // Apply the 'MayEscape' to all keys and values.
2796   processObjCLiterals(C, DL);
2797 }
2798 
checkPostStmt(const ObjCBoxedExpr * Ex,CheckerContext & C) const2799 void RetainCountChecker::checkPostStmt(const ObjCBoxedExpr *Ex,
2800                                        CheckerContext &C) const {
2801   const ExplodedNode *Pred = C.getPredecessor();
2802   const LocationContext *LCtx = Pred->getLocationContext();
2803   ProgramStateRef State = Pred->getState();
2804 
2805   if (SymbolRef Sym = State->getSVal(Ex, LCtx).getAsSymbol()) {
2806     QualType ResultTy = Ex->getType();
2807     State = setRefBinding(State, Sym,
2808                           RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
2809   }
2810 
2811   C.addTransition(State);
2812 }
2813 
wasLoadedFromIvar(SymbolRef Sym)2814 static bool wasLoadedFromIvar(SymbolRef Sym) {
2815   if (auto DerivedVal = dyn_cast<SymbolDerived>(Sym))
2816     return isa<ObjCIvarRegion>(DerivedVal->getRegion());
2817   if (auto RegionVal = dyn_cast<SymbolRegionValue>(Sym))
2818     return isa<ObjCIvarRegion>(RegionVal->getRegion());
2819   return false;
2820 }
2821 
checkPostStmt(const ObjCIvarRefExpr * IRE,CheckerContext & C) const2822 void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
2823                                        CheckerContext &C) const {
2824   Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>();
2825   if (!IVarLoc)
2826     return;
2827 
2828   ProgramStateRef State = C.getState();
2829   SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
2830   if (!Sym || !wasLoadedFromIvar(Sym))
2831     return;
2832 
2833   // Accessing an ivar directly is unusual. If we've done that, be more
2834   // forgiving about what the surrounding code is allowed to do.
2835 
2836   QualType Ty = Sym->getType();
2837   RetEffect::ObjKind Kind;
2838   if (Ty->isObjCRetainableType())
2839     Kind = RetEffect::ObjC;
2840   else if (coreFoundation::isCFObjectRef(Ty))
2841     Kind = RetEffect::CF;
2842   else
2843     return;
2844 
2845   // If the value is already known to be nil, don't bother tracking it.
2846   ConstraintManager &CMgr = State->getConstraintManager();
2847   if (CMgr.isNull(State, Sym).isConstrainedTrue())
2848     return;
2849 
2850   if (const RefVal *RV = getRefBinding(State, Sym)) {
2851     // If we've seen this symbol before, or we're only seeing it now because
2852     // of something the analyzer has synthesized, don't do anything.
2853     if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None ||
2854         isSynthesizedAccessor(C.getStackFrame())) {
2855       return;
2856     }
2857 
2858     // Note that this value has been loaded from an ivar.
2859     C.addTransition(setRefBinding(State, Sym, RV->withIvarAccess()));
2860     return;
2861   }
2862 
2863   RefVal PlusZero = RefVal::makeNotOwned(Kind, Ty);
2864 
2865   // In a synthesized accessor, the effective retain count is +0.
2866   if (isSynthesizedAccessor(C.getStackFrame())) {
2867     C.addTransition(setRefBinding(State, Sym, PlusZero));
2868     return;
2869   }
2870 
2871   State = setRefBinding(State, Sym, PlusZero.withIvarAccess());
2872   C.addTransition(State);
2873 }
2874 
checkPostCall(const CallEvent & Call,CheckerContext & C) const2875 void RetainCountChecker::checkPostCall(const CallEvent &Call,
2876                                        CheckerContext &C) const {
2877   RetainSummaryManager &Summaries = getSummaryManager(C);
2878   const RetainSummary *Summ = Summaries.getSummary(Call, C.getState());
2879 
2880   if (C.wasInlined) {
2881     processSummaryOfInlined(*Summ, Call, C);
2882     return;
2883   }
2884   checkSummary(*Summ, Call, C);
2885 }
2886 
2887 /// GetReturnType - Used to get the return type of a message expression or
2888 ///  function call with the intention of affixing that type to a tracked symbol.
2889 ///  While the return type can be queried directly from RetEx, when
2890 ///  invoking class methods we augment to the return type to be that of
2891 ///  a pointer to the class (as opposed it just being id).
2892 // FIXME: We may be able to do this with related result types instead.
2893 // This function is probably overestimating.
GetReturnType(const Expr * RetE,ASTContext & Ctx)2894 static QualType GetReturnType(const Expr *RetE, ASTContext &Ctx) {
2895   QualType RetTy = RetE->getType();
2896   // If RetE is not a message expression just return its type.
2897   // If RetE is a message expression, return its types if it is something
2898   /// more specific than id.
2899   if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
2900     if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>())
2901       if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
2902           PT->isObjCClassType()) {
2903         // At this point we know the return type of the message expression is
2904         // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
2905         // is a call to a class method whose type we can resolve.  In such
2906         // cases, promote the return type to XXX* (where XXX is the class).
2907         const ObjCInterfaceDecl *D = ME->getReceiverInterface();
2908         return !D ? RetTy :
2909                     Ctx.getObjCObjectPointerType(Ctx.getObjCInterfaceType(D));
2910       }
2911 
2912   return RetTy;
2913 }
2914 
2915 // We don't always get the exact modeling of the function with regards to the
2916 // retain count checker even when the function is inlined. For example, we need
2917 // to stop tracking the symbols which were marked with StopTrackingHard.
processSummaryOfInlined(const RetainSummary & Summ,const CallEvent & CallOrMsg,CheckerContext & C) const2918 void RetainCountChecker::processSummaryOfInlined(const RetainSummary &Summ,
2919                                                  const CallEvent &CallOrMsg,
2920                                                  CheckerContext &C) const {
2921   ProgramStateRef state = C.getState();
2922 
2923   // Evaluate the effect of the arguments.
2924   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
2925     if (Summ.getArg(idx) == StopTrackingHard) {
2926       SVal V = CallOrMsg.getArgSVal(idx);
2927       if (SymbolRef Sym = V.getAsLocSymbol()) {
2928         state = removeRefBinding(state, Sym);
2929       }
2930     }
2931   }
2932 
2933   // Evaluate the effect on the message receiver.
2934   const ObjCMethodCall *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg);
2935   if (MsgInvocation) {
2936     if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
2937       if (Summ.getReceiverEffect() == StopTrackingHard) {
2938         state = removeRefBinding(state, Sym);
2939       }
2940     }
2941   }
2942 
2943   // Consult the summary for the return value.
2944   RetEffect RE = Summ.getRetEffect();
2945   if (RE.getKind() == RetEffect::NoRetHard) {
2946     SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
2947     if (Sym)
2948       state = removeRefBinding(state, Sym);
2949   }
2950 
2951   C.addTransition(state);
2952 }
2953 
checkSummary(const RetainSummary & Summ,const CallEvent & CallOrMsg,CheckerContext & C) const2954 void RetainCountChecker::checkSummary(const RetainSummary &Summ,
2955                                       const CallEvent &CallOrMsg,
2956                                       CheckerContext &C) const {
2957   ProgramStateRef state = C.getState();
2958 
2959   // Evaluate the effect of the arguments.
2960   RefVal::Kind hasErr = (RefVal::Kind) 0;
2961   SourceRange ErrorRange;
2962   SymbolRef ErrorSym = nullptr;
2963 
2964   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
2965     SVal V = CallOrMsg.getArgSVal(idx);
2966 
2967     if (SymbolRef Sym = V.getAsLocSymbol()) {
2968       if (const RefVal *T = getRefBinding(state, Sym)) {
2969         state = updateSymbol(state, Sym, *T, Summ.getArg(idx), hasErr, C);
2970         if (hasErr) {
2971           ErrorRange = CallOrMsg.getArgSourceRange(idx);
2972           ErrorSym = Sym;
2973           break;
2974         }
2975       }
2976     }
2977   }
2978 
2979   // Evaluate the effect on the message receiver.
2980   bool ReceiverIsTracked = false;
2981   if (!hasErr) {
2982     const ObjCMethodCall *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg);
2983     if (MsgInvocation) {
2984       if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
2985         if (const RefVal *T = getRefBinding(state, Sym)) {
2986           ReceiverIsTracked = true;
2987           state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
2988                                  hasErr, C);
2989           if (hasErr) {
2990             ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
2991             ErrorSym = Sym;
2992           }
2993         }
2994       }
2995     }
2996   }
2997 
2998   // Process any errors.
2999   if (hasErr) {
3000     processNonLeakError(state, ErrorRange, hasErr, ErrorSym, C);
3001     return;
3002   }
3003 
3004   // Consult the summary for the return value.
3005   RetEffect RE = Summ.getRetEffect();
3006 
3007   if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
3008     if (ReceiverIsTracked)
3009       RE = getSummaryManager(C).getObjAllocRetEffect();
3010     else
3011       RE = RetEffect::MakeNoRet();
3012   }
3013 
3014   switch (RE.getKind()) {
3015     default:
3016       llvm_unreachable("Unhandled RetEffect.");
3017 
3018     case RetEffect::NoRet:
3019     case RetEffect::NoRetHard:
3020       // No work necessary.
3021       break;
3022 
3023     case RetEffect::OwnedAllocatedSymbol:
3024     case RetEffect::OwnedSymbol: {
3025       SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
3026       if (!Sym)
3027         break;
3028 
3029       // Use the result type from the CallEvent as it automatically adjusts
3030       // for methods/functions that return references.
3031       QualType ResultTy = CallOrMsg.getResultType();
3032       state = setRefBinding(state, Sym, RefVal::makeOwned(RE.getObjKind(),
3033                                                           ResultTy));
3034 
3035       // FIXME: Add a flag to the checker where allocations are assumed to
3036       // *not* fail.
3037       break;
3038     }
3039 
3040     case RetEffect::GCNotOwnedSymbol:
3041     case RetEffect::NotOwnedSymbol: {
3042       const Expr *Ex = CallOrMsg.getOriginExpr();
3043       SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
3044       if (!Sym)
3045         break;
3046       assert(Ex);
3047       // Use GetReturnType in order to give [NSFoo alloc] the type NSFoo *.
3048       QualType ResultTy = GetReturnType(Ex, C.getASTContext());
3049       state = setRefBinding(state, Sym, RefVal::makeNotOwned(RE.getObjKind(),
3050                                                              ResultTy));
3051       break;
3052     }
3053   }
3054 
3055   // This check is actually necessary; otherwise the statement builder thinks
3056   // we've hit a previously-found path.
3057   // Normally addTransition takes care of this, but we want the node pointer.
3058   ExplodedNode *NewNode;
3059   if (state == C.getState()) {
3060     NewNode = C.getPredecessor();
3061   } else {
3062     NewNode = C.addTransition(state);
3063   }
3064 
3065   // Annotate the node with summary we used.
3066   if (NewNode) {
3067     // FIXME: This is ugly. See checkEndAnalysis for why it's necessary.
3068     if (ShouldResetSummaryLog) {
3069       SummaryLog.clear();
3070       ShouldResetSummaryLog = false;
3071     }
3072     SummaryLog[NewNode] = &Summ;
3073   }
3074 }
3075 
3076 
3077 ProgramStateRef
updateSymbol(ProgramStateRef state,SymbolRef sym,RefVal V,ArgEffect E,RefVal::Kind & hasErr,CheckerContext & C) const3078 RetainCountChecker::updateSymbol(ProgramStateRef state, SymbolRef sym,
3079                                  RefVal V, ArgEffect E, RefVal::Kind &hasErr,
3080                                  CheckerContext &C) const {
3081   // In GC mode [... release] and [... retain] do nothing.
3082   // In ARC mode they shouldn't exist at all, but we just ignore them.
3083   bool IgnoreRetainMsg = C.isObjCGCEnabled();
3084   if (!IgnoreRetainMsg)
3085     IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
3086 
3087   switch (E) {
3088   default:
3089     break;
3090   case IncRefMsg:
3091     E = IgnoreRetainMsg ? DoNothing : IncRef;
3092     break;
3093   case DecRefMsg:
3094     E = IgnoreRetainMsg ? DoNothing : DecRef;
3095     break;
3096   case DecRefMsgAndStopTrackingHard:
3097     E = IgnoreRetainMsg ? StopTracking : DecRefAndStopTrackingHard;
3098     break;
3099   case MakeCollectable:
3100     E = C.isObjCGCEnabled() ? DecRef : DoNothing;
3101     break;
3102   }
3103 
3104   // Handle all use-after-releases.
3105   if (!C.isObjCGCEnabled() && V.getKind() == RefVal::Released) {
3106     V = V ^ RefVal::ErrorUseAfterRelease;
3107     hasErr = V.getKind();
3108     return setRefBinding(state, sym, V);
3109   }
3110 
3111   switch (E) {
3112     case DecRefMsg:
3113     case IncRefMsg:
3114     case MakeCollectable:
3115     case DecRefMsgAndStopTrackingHard:
3116       llvm_unreachable("DecRefMsg/IncRefMsg/MakeCollectable already converted");
3117 
3118     case Dealloc:
3119       // Any use of -dealloc in GC is *bad*.
3120       if (C.isObjCGCEnabled()) {
3121         V = V ^ RefVal::ErrorDeallocGC;
3122         hasErr = V.getKind();
3123         break;
3124       }
3125 
3126       switch (V.getKind()) {
3127         default:
3128           llvm_unreachable("Invalid RefVal state for an explicit dealloc.");
3129         case RefVal::Owned:
3130           // The object immediately transitions to the released state.
3131           V = V ^ RefVal::Released;
3132           V.clearCounts();
3133           return setRefBinding(state, sym, V);
3134         case RefVal::NotOwned:
3135           V = V ^ RefVal::ErrorDeallocNotOwned;
3136           hasErr = V.getKind();
3137           break;
3138       }
3139       break;
3140 
3141     case MayEscape:
3142       if (V.getKind() == RefVal::Owned) {
3143         V = V ^ RefVal::NotOwned;
3144         break;
3145       }
3146 
3147       // Fall-through.
3148 
3149     case DoNothing:
3150       return state;
3151 
3152     case Autorelease:
3153       if (C.isObjCGCEnabled())
3154         return state;
3155       // Update the autorelease counts.
3156       V = V.autorelease();
3157       break;
3158 
3159     case StopTracking:
3160     case StopTrackingHard:
3161       return removeRefBinding(state, sym);
3162 
3163     case IncRef:
3164       switch (V.getKind()) {
3165         default:
3166           llvm_unreachable("Invalid RefVal state for a retain.");
3167         case RefVal::Owned:
3168         case RefVal::NotOwned:
3169           V = V + 1;
3170           break;
3171         case RefVal::Released:
3172           // Non-GC cases are handled above.
3173           assert(C.isObjCGCEnabled());
3174           V = (V ^ RefVal::Owned) + 1;
3175           break;
3176       }
3177       break;
3178 
3179     case DecRef:
3180     case DecRefBridgedTransferred:
3181     case DecRefAndStopTrackingHard:
3182       switch (V.getKind()) {
3183         default:
3184           // case 'RefVal::Released' handled above.
3185           llvm_unreachable("Invalid RefVal state for a release.");
3186 
3187         case RefVal::Owned:
3188           assert(V.getCount() > 0);
3189           if (V.getCount() == 1) {
3190             if (E == DecRefBridgedTransferred ||
3191                 V.getIvarAccessHistory() ==
3192                   RefVal::IvarAccessHistory::AccessedDirectly)
3193               V = V ^ RefVal::NotOwned;
3194             else
3195               V = V ^ RefVal::Released;
3196           } else if (E == DecRefAndStopTrackingHard) {
3197             return removeRefBinding(state, sym);
3198           }
3199 
3200           V = V - 1;
3201           break;
3202 
3203         case RefVal::NotOwned:
3204           if (V.getCount() > 0) {
3205             if (E == DecRefAndStopTrackingHard)
3206               return removeRefBinding(state, sym);
3207             V = V - 1;
3208           } else if (V.getIvarAccessHistory() ==
3209                        RefVal::IvarAccessHistory::AccessedDirectly) {
3210             // Assume that the instance variable was holding on the object at
3211             // +1, and we just didn't know.
3212             if (E == DecRefAndStopTrackingHard)
3213               return removeRefBinding(state, sym);
3214             V = V.releaseViaIvar() ^ RefVal::Released;
3215           } else {
3216             V = V ^ RefVal::ErrorReleaseNotOwned;
3217             hasErr = V.getKind();
3218           }
3219           break;
3220 
3221         case RefVal::Released:
3222           // Non-GC cases are handled above.
3223           assert(C.isObjCGCEnabled());
3224           V = V ^ RefVal::ErrorUseAfterRelease;
3225           hasErr = V.getKind();
3226           break;
3227       }
3228       break;
3229   }
3230   return setRefBinding(state, sym, V);
3231 }
3232 
processNonLeakError(ProgramStateRef St,SourceRange ErrorRange,RefVal::Kind ErrorKind,SymbolRef Sym,CheckerContext & C) const3233 void RetainCountChecker::processNonLeakError(ProgramStateRef St,
3234                                              SourceRange ErrorRange,
3235                                              RefVal::Kind ErrorKind,
3236                                              SymbolRef Sym,
3237                                              CheckerContext &C) const {
3238   // HACK: Ignore retain-count issues on values accessed through ivars,
3239   // because of cases like this:
3240   //   [_contentView retain];
3241   //   [_contentView removeFromSuperview];
3242   //   [self addSubview:_contentView]; // invalidates 'self'
3243   //   [_contentView release];
3244   if (const RefVal *RV = getRefBinding(St, Sym))
3245     if (RV->getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
3246       return;
3247 
3248   ExplodedNode *N = C.generateSink(St);
3249   if (!N)
3250     return;
3251 
3252   CFRefBug *BT;
3253   switch (ErrorKind) {
3254     default:
3255       llvm_unreachable("Unhandled error.");
3256     case RefVal::ErrorUseAfterRelease:
3257       if (!useAfterRelease)
3258         useAfterRelease.reset(new UseAfterRelease(this));
3259       BT = &*useAfterRelease;
3260       break;
3261     case RefVal::ErrorReleaseNotOwned:
3262       if (!releaseNotOwned)
3263         releaseNotOwned.reset(new BadRelease(this));
3264       BT = &*releaseNotOwned;
3265       break;
3266     case RefVal::ErrorDeallocGC:
3267       if (!deallocGC)
3268         deallocGC.reset(new DeallocGC(this));
3269       BT = &*deallocGC;
3270       break;
3271     case RefVal::ErrorDeallocNotOwned:
3272       if (!deallocNotOwned)
3273         deallocNotOwned.reset(new DeallocNotOwned(this));
3274       BT = &*deallocNotOwned;
3275       break;
3276   }
3277 
3278   assert(BT);
3279   CFRefReport *report = new CFRefReport(*BT, C.getASTContext().getLangOpts(),
3280                                         C.isObjCGCEnabled(), SummaryLog,
3281                                         N, Sym);
3282   report->addRange(ErrorRange);
3283   C.emitReport(report);
3284 }
3285 
3286 //===----------------------------------------------------------------------===//
3287 // Handle the return values of retain-count-related functions.
3288 //===----------------------------------------------------------------------===//
3289 
evalCall(const CallExpr * CE,CheckerContext & C) const3290 bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
3291   // Get the callee. We're only interested in simple C functions.
3292   ProgramStateRef state = C.getState();
3293   const FunctionDecl *FD = C.getCalleeDecl(CE);
3294   if (!FD)
3295     return false;
3296 
3297   IdentifierInfo *II = FD->getIdentifier();
3298   if (!II)
3299     return false;
3300 
3301   // For now, we're only handling the functions that return aliases of their
3302   // arguments: CFRetain and CFMakeCollectable (and their families).
3303   // Eventually we should add other functions we can model entirely,
3304   // such as CFRelease, which don't invalidate their arguments or globals.
3305   if (CE->getNumArgs() != 1)
3306     return false;
3307 
3308   // Get the name of the function.
3309   StringRef FName = II->getName();
3310   FName = FName.substr(FName.find_first_not_of('_'));
3311 
3312   // See if it's one of the specific functions we know how to eval.
3313   bool canEval = false;
3314 
3315   QualType ResultTy = CE->getCallReturnType(C.getASTContext());
3316   if (ResultTy->isObjCIdType()) {
3317     // Handle: id NSMakeCollectable(CFTypeRef)
3318     canEval = II->isStr("NSMakeCollectable");
3319   } else if (ResultTy->isPointerType()) {
3320     // Handle: (CF|CG)Retain
3321     //         CFAutorelease
3322     //         CFMakeCollectable
3323     // It's okay to be a little sloppy here (CGMakeCollectable doesn't exist).
3324     if (cocoa::isRefType(ResultTy, "CF", FName) ||
3325         cocoa::isRefType(ResultTy, "CG", FName)) {
3326       canEval = isRetain(FD, FName) || isAutorelease(FD, FName) ||
3327                 isMakeCollectable(FD, FName);
3328     }
3329   }
3330 
3331   if (!canEval)
3332     return false;
3333 
3334   // Bind the return value.
3335   const LocationContext *LCtx = C.getLocationContext();
3336   SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
3337   if (RetVal.isUnknown()) {
3338     // If the receiver is unknown, conjure a return value.
3339     SValBuilder &SVB = C.getSValBuilder();
3340     RetVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
3341   }
3342   state = state->BindExpr(CE, LCtx, RetVal, false);
3343 
3344   // FIXME: This should not be necessary, but otherwise the argument seems to be
3345   // considered alive during the next statement.
3346   if (const MemRegion *ArgRegion = RetVal.getAsRegion()) {
3347     // Save the refcount status of the argument.
3348     SymbolRef Sym = RetVal.getAsLocSymbol();
3349     const RefVal *Binding = nullptr;
3350     if (Sym)
3351       Binding = getRefBinding(state, Sym);
3352 
3353     // Invalidate the argument region.
3354     state = state->invalidateRegions(ArgRegion, CE, C.blockCount(), LCtx,
3355                                      /*CausesPointerEscape*/ false);
3356 
3357     // Restore the refcount status of the argument.
3358     if (Binding)
3359       state = setRefBinding(state, Sym, *Binding);
3360   }
3361 
3362   C.addTransition(state);
3363   return true;
3364 }
3365 
3366 //===----------------------------------------------------------------------===//
3367 // Handle return statements.
3368 //===----------------------------------------------------------------------===//
3369 
checkPreStmt(const ReturnStmt * S,CheckerContext & C) const3370 void RetainCountChecker::checkPreStmt(const ReturnStmt *S,
3371                                       CheckerContext &C) const {
3372 
3373   // Only adjust the reference count if this is the top-level call frame,
3374   // and not the result of inlining.  In the future, we should do
3375   // better checking even for inlined calls, and see if they match
3376   // with their expected semantics (e.g., the method should return a retained
3377   // object, etc.).
3378   if (!C.inTopFrame())
3379     return;
3380 
3381   const Expr *RetE = S->getRetValue();
3382   if (!RetE)
3383     return;
3384 
3385   ProgramStateRef state = C.getState();
3386   SymbolRef Sym =
3387     state->getSValAsScalarOrLoc(RetE, C.getLocationContext()).getAsLocSymbol();
3388   if (!Sym)
3389     return;
3390 
3391   // Get the reference count binding (if any).
3392   const RefVal *T = getRefBinding(state, Sym);
3393   if (!T)
3394     return;
3395 
3396   // Change the reference count.
3397   RefVal X = *T;
3398 
3399   switch (X.getKind()) {
3400     case RefVal::Owned: {
3401       unsigned cnt = X.getCount();
3402       assert(cnt > 0);
3403       X.setCount(cnt - 1);
3404       X = X ^ RefVal::ReturnedOwned;
3405       break;
3406     }
3407 
3408     case RefVal::NotOwned: {
3409       unsigned cnt = X.getCount();
3410       if (cnt) {
3411         X.setCount(cnt - 1);
3412         X = X ^ RefVal::ReturnedOwned;
3413       }
3414       else {
3415         X = X ^ RefVal::ReturnedNotOwned;
3416       }
3417       break;
3418     }
3419 
3420     default:
3421       return;
3422   }
3423 
3424   // Update the binding.
3425   state = setRefBinding(state, Sym, X);
3426   ExplodedNode *Pred = C.addTransition(state);
3427 
3428   // At this point we have updated the state properly.
3429   // Everything after this is merely checking to see if the return value has
3430   // been over- or under-retained.
3431 
3432   // Did we cache out?
3433   if (!Pred)
3434     return;
3435 
3436   // Update the autorelease counts.
3437   static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
3438   state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X);
3439 
3440   // Did we cache out?
3441   if (!state)
3442     return;
3443 
3444   // Get the updated binding.
3445   T = getRefBinding(state, Sym);
3446   assert(T);
3447   X = *T;
3448 
3449   // Consult the summary of the enclosing method.
3450   RetainSummaryManager &Summaries = getSummaryManager(C);
3451   const Decl *CD = &Pred->getCodeDecl();
3452   RetEffect RE = RetEffect::MakeNoRet();
3453 
3454   // FIXME: What is the convention for blocks? Is there one?
3455   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
3456     const RetainSummary *Summ = Summaries.getMethodSummary(MD);
3457     RE = Summ->getRetEffect();
3458   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
3459     if (!isa<CXXMethodDecl>(FD)) {
3460       const RetainSummary *Summ = Summaries.getFunctionSummary(FD);
3461       RE = Summ->getRetEffect();
3462     }
3463   }
3464 
3465   checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
3466 }
3467 
checkReturnWithRetEffect(const ReturnStmt * S,CheckerContext & C,ExplodedNode * Pred,RetEffect RE,RefVal X,SymbolRef Sym,ProgramStateRef state) const3468 void RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S,
3469                                                   CheckerContext &C,
3470                                                   ExplodedNode *Pred,
3471                                                   RetEffect RE, RefVal X,
3472                                                   SymbolRef Sym,
3473                                               ProgramStateRef state) const {
3474   // HACK: Ignore retain-count issues on values accessed through ivars,
3475   // because of cases like this:
3476   //   [_contentView retain];
3477   //   [_contentView removeFromSuperview];
3478   //   [self addSubview:_contentView]; // invalidates 'self'
3479   //   [_contentView release];
3480   if (X.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
3481     return;
3482 
3483   // Any leaks or other errors?
3484   if (X.isReturnedOwned() && X.getCount() == 0) {
3485     if (RE.getKind() != RetEffect::NoRet) {
3486       bool hasError = false;
3487       if (C.isObjCGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
3488         // Things are more complicated with garbage collection.  If the
3489         // returned object is suppose to be an Objective-C object, we have
3490         // a leak (as the caller expects a GC'ed object) because no
3491         // method should return ownership unless it returns a CF object.
3492         hasError = true;
3493         X = X ^ RefVal::ErrorGCLeakReturned;
3494       }
3495       else if (!RE.isOwned()) {
3496         // Either we are using GC and the returned object is a CF type
3497         // or we aren't using GC.  In either case, we expect that the
3498         // enclosing method is expected to return ownership.
3499         hasError = true;
3500         X = X ^ RefVal::ErrorLeakReturned;
3501       }
3502 
3503       if (hasError) {
3504         // Generate an error node.
3505         state = setRefBinding(state, Sym, X);
3506 
3507         static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
3508         ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
3509         if (N) {
3510           const LangOptions &LOpts = C.getASTContext().getLangOpts();
3511           bool GCEnabled = C.isObjCGCEnabled();
3512           CFRefReport *report =
3513             new CFRefLeakReport(*getLeakAtReturnBug(LOpts, GCEnabled),
3514                                 LOpts, GCEnabled, SummaryLog,
3515                                 N, Sym, C, IncludeAllocationLine);
3516 
3517           C.emitReport(report);
3518         }
3519       }
3520     }
3521   } else if (X.isReturnedNotOwned()) {
3522     if (RE.isOwned()) {
3523       if (X.getIvarAccessHistory() ==
3524             RefVal::IvarAccessHistory::AccessedDirectly) {
3525         // Assume the method was trying to transfer a +1 reference from a
3526         // strong ivar to the caller.
3527         state = setRefBinding(state, Sym,
3528                               X.releaseViaIvar() ^ RefVal::ReturnedOwned);
3529       } else {
3530         // Trying to return a not owned object to a caller expecting an
3531         // owned object.
3532         state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
3533 
3534         static CheckerProgramPointTag
3535             ReturnNotOwnedTag(this, "ReturnNotOwnedForOwned");
3536 
3537         ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
3538         if (N) {
3539           if (!returnNotOwnedForOwned)
3540             returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
3541 
3542           CFRefReport *report =
3543               new CFRefReport(*returnNotOwnedForOwned,
3544                               C.getASTContext().getLangOpts(),
3545                               C.isObjCGCEnabled(), SummaryLog, N, Sym);
3546           C.emitReport(report);
3547         }
3548       }
3549     }
3550   }
3551 }
3552 
3553 //===----------------------------------------------------------------------===//
3554 // Check various ways a symbol can be invalidated.
3555 //===----------------------------------------------------------------------===//
3556 
checkBind(SVal loc,SVal val,const Stmt * S,CheckerContext & C) const3557 void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
3558                                    CheckerContext &C) const {
3559   // Are we storing to something that causes the value to "escape"?
3560   bool escapes = true;
3561 
3562   // A value escapes in three possible cases (this may change):
3563   //
3564   // (1) we are binding to something that is not a memory region.
3565   // (2) we are binding to a memregion that does not have stack storage
3566   // (3) we are binding to a memregion with stack storage that the store
3567   //     does not understand.
3568   ProgramStateRef state = C.getState();
3569 
3570   if (Optional<loc::MemRegionVal> regionLoc = loc.getAs<loc::MemRegionVal>()) {
3571     escapes = !regionLoc->getRegion()->hasStackStorage();
3572 
3573     if (!escapes) {
3574       // To test (3), generate a new state with the binding added.  If it is
3575       // the same state, then it escapes (since the store cannot represent
3576       // the binding).
3577       // Do this only if we know that the store is not supposed to generate the
3578       // same state.
3579       SVal StoredVal = state->getSVal(regionLoc->getRegion());
3580       if (StoredVal != val)
3581         escapes = (state == (state->bindLoc(*regionLoc, val)));
3582     }
3583     if (!escapes) {
3584       // Case 4: We do not currently model what happens when a symbol is
3585       // assigned to a struct field, so be conservative here and let the symbol
3586       // go. TODO: This could definitely be improved upon.
3587       escapes = !isa<VarRegion>(regionLoc->getRegion());
3588     }
3589   }
3590 
3591   // If we are storing the value into an auto function scope variable annotated
3592   // with (__attribute__((cleanup))), stop tracking the value to avoid leak
3593   // false positives.
3594   if (const VarRegion *LVR = dyn_cast_or_null<VarRegion>(loc.getAsRegion())) {
3595     const VarDecl *VD = LVR->getDecl();
3596     if (VD->hasAttr<CleanupAttr>()) {
3597       escapes = true;
3598     }
3599   }
3600 
3601   // If our store can represent the binding and we aren't storing to something
3602   // that doesn't have local storage then just return and have the simulation
3603   // state continue as is.
3604   if (!escapes)
3605       return;
3606 
3607   // Otherwise, find all symbols referenced by 'val' that we are tracking
3608   // and stop tracking them.
3609   state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
3610   C.addTransition(state);
3611 }
3612 
evalAssume(ProgramStateRef state,SVal Cond,bool Assumption) const3613 ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
3614                                                    SVal Cond,
3615                                                    bool Assumption) const {
3616 
3617   // FIXME: We may add to the interface of evalAssume the list of symbols
3618   //  whose assumptions have changed.  For now we just iterate through the
3619   //  bindings and check if any of the tracked symbols are NULL.  This isn't
3620   //  too bad since the number of symbols we will track in practice are
3621   //  probably small and evalAssume is only called at branches and a few
3622   //  other places.
3623   RefBindingsTy B = state->get<RefBindings>();
3624 
3625   if (B.isEmpty())
3626     return state;
3627 
3628   bool changed = false;
3629   RefBindingsTy::Factory &RefBFactory = state->get_context<RefBindings>();
3630 
3631   for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
3632     // Check if the symbol is null stop tracking the symbol.
3633     ConstraintManager &CMgr = state->getConstraintManager();
3634     ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
3635     if (AllocFailed.isConstrainedTrue()) {
3636       changed = true;
3637       B = RefBFactory.remove(B, I.getKey());
3638     }
3639   }
3640 
3641   if (changed)
3642     state = state->set<RefBindings>(B);
3643 
3644   return state;
3645 }
3646 
3647 ProgramStateRef
checkRegionChanges(ProgramStateRef state,const InvalidatedSymbols * invalidated,ArrayRef<const MemRegion * > ExplicitRegions,ArrayRef<const MemRegion * > Regions,const CallEvent * Call) const3648 RetainCountChecker::checkRegionChanges(ProgramStateRef state,
3649                                     const InvalidatedSymbols *invalidated,
3650                                     ArrayRef<const MemRegion *> ExplicitRegions,
3651                                     ArrayRef<const MemRegion *> Regions,
3652                                     const CallEvent *Call) const {
3653   if (!invalidated)
3654     return state;
3655 
3656   llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols;
3657   for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
3658        E = ExplicitRegions.end(); I != E; ++I) {
3659     if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs<SymbolicRegion>())
3660       WhitelistedSymbols.insert(SR->getSymbol());
3661   }
3662 
3663   for (InvalidatedSymbols::const_iterator I=invalidated->begin(),
3664        E = invalidated->end(); I!=E; ++I) {
3665     SymbolRef sym = *I;
3666     if (WhitelistedSymbols.count(sym))
3667       continue;
3668     // Remove any existing reference-count binding.
3669     state = removeRefBinding(state, sym);
3670   }
3671   return state;
3672 }
3673 
3674 //===----------------------------------------------------------------------===//
3675 // Handle dead symbols and end-of-path.
3676 //===----------------------------------------------------------------------===//
3677 
3678 ProgramStateRef
handleAutoreleaseCounts(ProgramStateRef state,ExplodedNode * Pred,const ProgramPointTag * Tag,CheckerContext & Ctx,SymbolRef Sym,RefVal V) const3679 RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state,
3680                                             ExplodedNode *Pred,
3681                                             const ProgramPointTag *Tag,
3682                                             CheckerContext &Ctx,
3683                                             SymbolRef Sym, RefVal V) const {
3684   unsigned ACnt = V.getAutoreleaseCount();
3685 
3686   // No autorelease counts?  Nothing to be done.
3687   if (!ACnt)
3688     return state;
3689 
3690   assert(!Ctx.isObjCGCEnabled() && "Autorelease counts in GC mode?");
3691   unsigned Cnt = V.getCount();
3692 
3693   // FIXME: Handle sending 'autorelease' to already released object.
3694 
3695   if (V.getKind() == RefVal::ReturnedOwned)
3696     ++Cnt;
3697 
3698   // If we would over-release here, but we know the value came from an ivar,
3699   // assume it was a strong ivar that's just been relinquished.
3700   if (ACnt > Cnt &&
3701       V.getIvarAccessHistory() == RefVal::IvarAccessHistory::AccessedDirectly) {
3702     V = V.releaseViaIvar();
3703     --ACnt;
3704   }
3705 
3706   if (ACnt <= Cnt) {
3707     if (ACnt == Cnt) {
3708       V.clearCounts();
3709       if (V.getKind() == RefVal::ReturnedOwned)
3710         V = V ^ RefVal::ReturnedNotOwned;
3711       else
3712         V = V ^ RefVal::NotOwned;
3713     } else {
3714       V.setCount(V.getCount() - ACnt);
3715       V.setAutoreleaseCount(0);
3716     }
3717     return setRefBinding(state, Sym, V);
3718   }
3719 
3720   // HACK: Ignore retain-count issues on values accessed through ivars,
3721   // because of cases like this:
3722   //   [_contentView retain];
3723   //   [_contentView removeFromSuperview];
3724   //   [self addSubview:_contentView]; // invalidates 'self'
3725   //   [_contentView release];
3726   if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
3727     return state;
3728 
3729   // Woah!  More autorelease counts then retain counts left.
3730   // Emit hard error.
3731   V = V ^ RefVal::ErrorOverAutorelease;
3732   state = setRefBinding(state, Sym, V);
3733 
3734   ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
3735   if (N) {
3736     SmallString<128> sbuf;
3737     llvm::raw_svector_ostream os(sbuf);
3738     os << "Object was autoreleased ";
3739     if (V.getAutoreleaseCount() > 1)
3740       os << V.getAutoreleaseCount() << " times but the object ";
3741     else
3742       os << "but ";
3743     os << "has a +" << V.getCount() << " retain count";
3744 
3745     if (!overAutorelease)
3746       overAutorelease.reset(new OverAutorelease(this));
3747 
3748     const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
3749     CFRefReport *report =
3750       new CFRefReport(*overAutorelease, LOpts, /* GCEnabled = */ false,
3751                       SummaryLog, N, Sym, os.str());
3752     Ctx.emitReport(report);
3753   }
3754 
3755   return nullptr;
3756 }
3757 
3758 ProgramStateRef
handleSymbolDeath(ProgramStateRef state,SymbolRef sid,RefVal V,SmallVectorImpl<SymbolRef> & Leaked) const3759 RetainCountChecker::handleSymbolDeath(ProgramStateRef state,
3760                                       SymbolRef sid, RefVal V,
3761                                     SmallVectorImpl<SymbolRef> &Leaked) const {
3762   bool hasLeak;
3763 
3764   // HACK: Ignore retain-count issues on values accessed through ivars,
3765   // because of cases like this:
3766   //   [_contentView retain];
3767   //   [_contentView removeFromSuperview];
3768   //   [self addSubview:_contentView]; // invalidates 'self'
3769   //   [_contentView release];
3770   if (V.getIvarAccessHistory() != RefVal::IvarAccessHistory::None)
3771     hasLeak = false;
3772   else if (V.isOwned())
3773     hasLeak = true;
3774   else if (V.isNotOwned() || V.isReturnedOwned())
3775     hasLeak = (V.getCount() > 0);
3776   else
3777     hasLeak = false;
3778 
3779   if (!hasLeak)
3780     return removeRefBinding(state, sid);
3781 
3782   Leaked.push_back(sid);
3783   return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
3784 }
3785 
3786 ExplodedNode *
processLeaks(ProgramStateRef state,SmallVectorImpl<SymbolRef> & Leaked,CheckerContext & Ctx,ExplodedNode * Pred) const3787 RetainCountChecker::processLeaks(ProgramStateRef state,
3788                                  SmallVectorImpl<SymbolRef> &Leaked,
3789                                  CheckerContext &Ctx,
3790                                  ExplodedNode *Pred) const {
3791   // Generate an intermediate node representing the leak point.
3792   ExplodedNode *N = Ctx.addTransition(state, Pred);
3793 
3794   if (N) {
3795     for (SmallVectorImpl<SymbolRef>::iterator
3796          I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
3797 
3798       const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
3799       bool GCEnabled = Ctx.isObjCGCEnabled();
3800       CFRefBug *BT = Pred ? getLeakWithinFunctionBug(LOpts, GCEnabled)
3801                           : getLeakAtReturnBug(LOpts, GCEnabled);
3802       assert(BT && "BugType not initialized.");
3803 
3804       CFRefLeakReport *report = new CFRefLeakReport(*BT, LOpts, GCEnabled,
3805                                                     SummaryLog, N, *I, Ctx,
3806                                                     IncludeAllocationLine);
3807       Ctx.emitReport(report);
3808     }
3809   }
3810 
3811   return N;
3812 }
3813 
checkEndFunction(CheckerContext & Ctx) const3814 void RetainCountChecker::checkEndFunction(CheckerContext &Ctx) const {
3815   ProgramStateRef state = Ctx.getState();
3816   RefBindingsTy B = state->get<RefBindings>();
3817   ExplodedNode *Pred = Ctx.getPredecessor();
3818 
3819   // Don't process anything within synthesized bodies.
3820   const LocationContext *LCtx = Pred->getLocationContext();
3821   if (LCtx->getAnalysisDeclContext()->isBodyAutosynthesized()) {
3822     assert(LCtx->getParent());
3823     return;
3824   }
3825 
3826   for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
3827     state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
3828                                     I->first, I->second);
3829     if (!state)
3830       return;
3831   }
3832 
3833   // If the current LocationContext has a parent, don't check for leaks.
3834   // We will do that later.
3835   // FIXME: we should instead check for imbalances of the retain/releases,
3836   // and suggest annotations.
3837   if (LCtx->getParent())
3838     return;
3839 
3840   B = state->get<RefBindings>();
3841   SmallVector<SymbolRef, 10> Leaked;
3842 
3843   for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I)
3844     state = handleSymbolDeath(state, I->first, I->second, Leaked);
3845 
3846   processLeaks(state, Leaked, Ctx, Pred);
3847 }
3848 
3849 const ProgramPointTag *
getDeadSymbolTag(SymbolRef sym) const3850 RetainCountChecker::getDeadSymbolTag(SymbolRef sym) const {
3851   const CheckerProgramPointTag *&tag = DeadSymbolTags[sym];
3852   if (!tag) {
3853     SmallString<64> buf;
3854     llvm::raw_svector_ostream out(buf);
3855     out << "Dead Symbol : ";
3856     sym->dumpToStream(out);
3857     tag = new CheckerProgramPointTag(this, out.str());
3858   }
3859   return tag;
3860 }
3861 
checkDeadSymbols(SymbolReaper & SymReaper,CheckerContext & C) const3862 void RetainCountChecker::checkDeadSymbols(SymbolReaper &SymReaper,
3863                                           CheckerContext &C) const {
3864   ExplodedNode *Pred = C.getPredecessor();
3865 
3866   ProgramStateRef state = C.getState();
3867   RefBindingsTy B = state->get<RefBindings>();
3868   SmallVector<SymbolRef, 10> Leaked;
3869 
3870   // Update counts from autorelease pools
3871   for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
3872        E = SymReaper.dead_end(); I != E; ++I) {
3873     SymbolRef Sym = *I;
3874     if (const RefVal *T = B.lookup(Sym)){
3875       // Use the symbol as the tag.
3876       // FIXME: This might not be as unique as we would like.
3877       const ProgramPointTag *Tag = getDeadSymbolTag(Sym);
3878       state = handleAutoreleaseCounts(state, Pred, Tag, C, Sym, *T);
3879       if (!state)
3880         return;
3881 
3882       // Fetch the new reference count from the state, and use it to handle
3883       // this symbol.
3884       state = handleSymbolDeath(state, *I, *getRefBinding(state, Sym), Leaked);
3885     }
3886   }
3887 
3888   if (Leaked.empty()) {
3889     C.addTransition(state);
3890     return;
3891   }
3892 
3893   Pred = processLeaks(state, Leaked, C, Pred);
3894 
3895   // Did we cache out?
3896   if (!Pred)
3897     return;
3898 
3899   // Now generate a new node that nukes the old bindings.
3900   // The only bindings left at this point are the leaked symbols.
3901   RefBindingsTy::Factory &F = state->get_context<RefBindings>();
3902   B = state->get<RefBindings>();
3903 
3904   for (SmallVectorImpl<SymbolRef>::iterator I = Leaked.begin(),
3905                                             E = Leaked.end();
3906        I != E; ++I)
3907     B = F.remove(B, *I);
3908 
3909   state = state->set<RefBindings>(B);
3910   C.addTransition(state, Pred);
3911 }
3912 
printState(raw_ostream & Out,ProgramStateRef State,const char * NL,const char * Sep) const3913 void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
3914                                     const char *NL, const char *Sep) const {
3915 
3916   RefBindingsTy B = State->get<RefBindings>();
3917 
3918   if (B.isEmpty())
3919     return;
3920 
3921   Out << Sep << NL;
3922 
3923   for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
3924     Out << I->first << " : ";
3925     I->second.print(Out);
3926     Out << NL;
3927   }
3928 }
3929 
3930 //===----------------------------------------------------------------------===//
3931 // Checker registration.
3932 //===----------------------------------------------------------------------===//
3933 
registerRetainCountChecker(CheckerManager & Mgr)3934 void ento::registerRetainCountChecker(CheckerManager &Mgr) {
3935   Mgr.registerChecker<RetainCountChecker>(Mgr.getAnalyzerOptions());
3936 }
3937 
3938 //===----------------------------------------------------------------------===//
3939 // Implementation of the CallEffects API.
3940 //===----------------------------------------------------------------------===//
3941 
3942 namespace clang { namespace ento { namespace objc_retain {
3943 
3944 // This is a bit gross, but it allows us to populate CallEffects without
3945 // creating a bunch of accessors.  This kind is very localized, so the
3946 // damage of this macro is limited.
3947 #define createCallEffect(D, KIND)\
3948   ASTContext &Ctx = D->getASTContext();\
3949   LangOptions L = Ctx.getLangOpts();\
3950   RetainSummaryManager M(Ctx, L.GCOnly, L.ObjCAutoRefCount);\
3951   const RetainSummary *S = M.get ## KIND ## Summary(D);\
3952   CallEffects CE(S->getRetEffect());\
3953   CE.Receiver = S->getReceiverEffect();\
3954   unsigned N = D->param_size();\
3955   for (unsigned i = 0; i < N; ++i) {\
3956     CE.Args.push_back(S->getArg(i));\
3957   }
3958 
getEffect(const ObjCMethodDecl * MD)3959 CallEffects CallEffects::getEffect(const ObjCMethodDecl *MD) {
3960   createCallEffect(MD, Method);
3961   return CE;
3962 }
3963 
getEffect(const FunctionDecl * FD)3964 CallEffects CallEffects::getEffect(const FunctionDecl *FD) {
3965   createCallEffect(FD, Function);
3966   return CE;
3967 }
3968 
3969 #undef createCallEffect
3970 
3971 }}}
3972