zcov: / lib/Checker/CFRefCount.cpp


Files: 1 Branches Taken: 75.2% 675 / 898
Generated: 2010-02-10 01:31 Branches Executed: 89.9% 807 / 898
Line Coverage: 90.9% 1195 / 1314


Programs: 1 Runs 2897


       1                 : // CFRefCount.cpp - Transfer functions for tracking simple values -*- 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 CFRefCount, which implements
      11                 : //  a reference count checker for Core Foundation (Mac OS X).
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #include "clang/Basic/LangOptions.h"
      16                 : #include "clang/Basic/SourceManager.h"
      17                 : #include "clang/Checker/PathSensitive/GRExprEngineBuilders.h"
      18                 : #include "clang/Checker/PathSensitive/GRStateTrait.h"
      19                 : #include "clang/Checker/BugReporter/PathDiagnostic.h"
      20                 : #include "clang/Checker/Checkers/LocalCheckers.h"
      21                 : #include "clang/Checker/BugReporter/PathDiagnostic.h"
      22                 : #include "clang/Checker/BugReporter/BugReporter.h"
      23                 : #include "clang/Checker/PathSensitive/SymbolManager.h"
      24                 : #include "clang/Checker/PathSensitive/GRTransferFuncs.h"
      25                 : #include "clang/Checker/PathSensitive/CheckerVisitor.h"
      26                 : #include "clang/Checker/DomainSpecific/CocoaConventions.h"
      27                 : #include "clang/AST/DeclObjC.h"
      28                 : #include "clang/AST/StmtVisitor.h"
      29                 : #include "llvm/ADT/DenseMap.h"
      30                 : #include "llvm/ADT/FoldingSet.h"
      31                 : #include "llvm/ADT/ImmutableMap.h"
      32                 : #include "llvm/ADT/ImmutableList.h"
      33                 : #include "llvm/ADT/StringExtras.h"
      34                 : #include "llvm/ADT/STLExtras.h"
      35                 : #include <stdarg.h>
      36                 : 
      37                 : using namespace clang;
      38                 : using llvm::StringRef;
      39                 : using llvm::StrInStrNoCase;
      40                 : 
      41                 : static const ObjCMethodDecl*
      42               66: ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {
      43                 :   ObjCInterfaceDecl *ID =
      44               66:     const_cast<ObjCInterfaceDecl*>(MD->getClassInterface());
      45                 : 
      46                 :   return MD->isInstanceMethod()
      47                 :          ? ID->lookupInstanceMethod(MD->getSelector())
                       54: branch 1 taken
                       12: branch 2 taken
      48               66:          : ID->lookupClassMethod(MD->getSelector());
      49                 : }
      50                 : 
      51                 : namespace {
      52                 : class GenericNodeBuilder {
      53                 :   GRStmtNodeBuilder *SNB;
      54                 :   Stmt *S;
      55                 :   const void *tag;
      56                 :   GREndPathNodeBuilder *ENB;
      57                 : public:
      58                 :   GenericNodeBuilder(GRStmtNodeBuilder &snb, Stmt *s,
      59             1388:                      const void *t)
      60             1388:   : SNB(&snb), S(s), tag(t), ENB(0) {}
      61                 : 
      62             2600:   GenericNodeBuilder(GREndPathNodeBuilder &enb)
      63             2600:   : SNB(0), S(0), tag(0), ENB(&enb) {}
      64                 : 
      65              208:   ExplodedNode *MakeNode(const GRState *state, ExplodedNode *Pred) {
                       85: branch 0 taken
                      123: branch 1 taken
      66              208:     if (SNB)
      67                 :       return SNB->generateNode(PostStmt(S, Pred->getLocationContext(), tag),
      68               85:                                state, Pred);
      69                 : 
                        0: branch 0 not taken
                      123: branch 1 taken
      70              123:     assert(ENB);
      71              123:     return ENB->generateNode(state, Pred);
      72                 :   }
      73                 : };
      74                 : } // end anonymous namespace
      75                 : 
      76                 : //===----------------------------------------------------------------------===//
      77                 : // Primitives used for constructing summaries for function/method calls.
      78                 : //===----------------------------------------------------------------------===//
      79                 : 
      80                 : /// ArgEffect is used to summarize a function/method call's effect on a
      81                 : /// particular argument.
      82                 : enum ArgEffect { Autorelease, Dealloc, DecRef, DecRefMsg, DoNothing,
      83                 :                  DoNothingByRef, IncRefMsg, IncRef, MakeCollectable, MayEscape,
      84                 :                  NewAutoreleasePool, SelfOwn, StopTracking };
      85                 : 
      86                 : namespace llvm {
      87                 : template <> struct FoldingSetTrait<ArgEffect> {
      88             2364: static inline void Profile(const ArgEffect X, FoldingSetNodeID& ID) {
      89             2364:   ID.AddInteger((unsigned) X);
      90             2364: }
      91                 : };
      92                 : } // end llvm namespace
      93                 : 
      94                 : /// ArgEffects summarizes the effects of a function/method call on all of
      95                 : /// its arguments.
      96                 : typedef llvm::ImmutableMap<unsigned,ArgEffect> ArgEffects;
      97                 : 
      98                 : namespace {
      99                 : 
     100                 : ///  RetEffect is used to summarize a function/method call's behavior with
     101                 : ///  respect to its return value.
     102                 : class RetEffect {
     103                 : public:
     104                 :   enum Kind { NoRet, Alias, OwnedSymbol, OwnedAllocatedSymbol,
     105                 :               NotOwnedSymbol, GCNotOwnedSymbol, ReceiverAlias,
     106                 :               OwnedWhenTrackedReceiver };
     107                 : 
     108                 :   enum ObjKind { CF, ObjC, AnyObj };
     109                 : 
     110                 : private:
     111                 :   Kind K;
     112                 :   ObjKind O;
     113                 :   unsigned index;
     114                 : 
     115            21887:   RetEffect(Kind k, unsigned idx = 0) : K(k), O(AnyObj), index(idx) {}
     116            11109:   RetEffect(Kind k, ObjKind o) : K(k), O(o), index(0) {}
     117                 : 
     118                 : public:
     119             5560:   Kind getKind() const { return K; }
     120                 : 
     121              909:   ObjKind getObjKind() const { return O; }
     122                 : 
     123              136:   unsigned getIndex() const {
                        0: branch 1 not taken
                      136: branch 2 taken
     124              136:     assert(getKind() == Alias);
     125              136:     return index;
     126                 :   }
     127                 : 
     128               58:   bool isOwned() const {
     129                 :     return K == OwnedSymbol || K == OwnedAllocatedSymbol ||
                       58: branch 0 taken
                        0: branch 1 not taken
                       32: branch 2 taken
                       26: branch 3 taken
                        6: branch 4 taken
                       26: branch 5 taken
     130               58:            K == OwnedWhenTrackedReceiver;
     131                 :   }
     132                 : 
     133             1900:   static RetEffect MakeOwnedWhenTrackedReceiver() {
     134             1900:     return RetEffect(OwnedWhenTrackedReceiver, ObjC);
     135                 :   }
     136                 : 
     137              120:   static RetEffect MakeAlias(unsigned Idx) {
     138              120:     return RetEffect(Alias, Idx);
     139                 :   }
     140             4276:   static RetEffect MakeReceiverAlias() {
     141             4276:     return RetEffect(ReceiverAlias);
     142                 :   }
     143             4315:   static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
                     4315: branch 0 taken
                        0: branch 1 not taken
     144             4315:     return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
     145                 :   }
     146             4418:   static RetEffect MakeNotOwned(ObjKind o) {
     147             4418:     return RetEffect(NotOwnedSymbol, o);
     148                 :   }
     149              476:   static RetEffect MakeGCNotOwned() {
     150              476:     return RetEffect(GCNotOwnedSymbol, ObjC);
     151                 :   }
     152                 : 
     153            17491:   static RetEffect MakeNoRet() {
     154            17491:     return RetEffect(NoRet);
     155                 :   }
     156                 : 
     157                 :   void Profile(llvm::FoldingSetNodeID& ID) const {
     158                 :     ID.AddInteger((unsigned)K);
     159                 :     ID.AddInteger((unsigned)O);
     160                 :     ID.AddInteger(index);
     161                 :   }
     162                 : };
     163                 : 
     164                 : //===----------------------------------------------------------------------===//
     165                 : // Reference-counting logic (typestate + counts).
     166                 : //===----------------------------------------------------------------------===//
     167                 : 
     168                 : class RefVal {
     169                 : public:
     170                 :   enum Kind {
     171                 :     Owned = 0, // Owning reference.
     172                 :     NotOwned,  // Reference is not owned by still valid (not freed).
     173                 :     Released,  // Object has been released.
     174                 :     ReturnedOwned, // Returned object passes ownership to caller.
     175                 :     ReturnedNotOwned, // Return object does not pass ownership to caller.
     176                 :     ERROR_START,
     177                 :     ErrorDeallocNotOwned, // -dealloc called on non-owned object.
     178                 :     ErrorDeallocGC, // Calling -dealloc with GC enabled.
     179                 :     ErrorUseAfterRelease, // Object used after released.
     180                 :     ErrorReleaseNotOwned, // Release of an object that was not owned.
     181                 :     ERROR_LEAK_START,
     182                 :     ErrorLeak,  // A memory leak due to excessive reference counts.
     183                 :     ErrorLeakReturned, // A memory leak due to the returning method not having
     184                 :                        // the correct naming conventions.
     185                 :     ErrorGCLeakReturned,
     186                 :     ErrorOverAutorelease,
     187                 :     ErrorReturnedNotOwned
     188                 :   };
     189                 :   
     190                 : private:
     191                 :   Kind kind;
     192                 :   RetEffect::ObjKind okind;
     193                 :   unsigned Cnt;
     194                 :   unsigned ACnt;
     195                 :   QualType T;
     196                 :   
     197             2343:   RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t)
     198             2343:   : kind(k), okind(o), Cnt(cnt), ACnt(acnt), T(t) {}
     199                 :   
     200                 :   RefVal(Kind k, unsigned cnt = 0)
     201                 :   : kind(k), okind(RetEffect::AnyObj), Cnt(cnt), ACnt(0) {}
     202                 :   
     203                 : public:
     204             5231:   Kind getKind() const { return kind; }
     205                 :   
     206             1802:   RetEffect::ObjKind getObjKind() const { return okind; }
     207                 :   
     208             3487:   unsigned getCount() const { return Cnt; }
     209             2429:   unsigned getAutoreleaseCount() const { return ACnt; }
     210                2:   unsigned getCombinedCounts() const { return Cnt + ACnt; }
     211               50:   void clearCounts() { Cnt = 0; ACnt = 0; }
     212              105:   void setCount(unsigned i) { Cnt = i; }
     213                8:   void setAutoreleaseCount(unsigned i) { ACnt = i; }
     214                 :   
     215             2021:   QualType getType() const { return T; }
     216                 :   
     217                 :   // Useful predicates.
     218                 :   
     219                 :   static bool isError(Kind k) { return k >= ERROR_START; }
     220                 :   
     221                 :   static bool isLeak(Kind k) { return k >= ERROR_LEAK_START; }
     222                 :   
     223              995:   bool isOwned() const {
     224              995:     return getKind() == Owned;
     225                 :   }
     226                 :   
     227              632:   bool isNotOwned() const {
     228              632:     return getKind() == NotOwned;
     229                 :   }
     230                 :   
     231              539:   bool isReturnedOwned() const {
     232              539:     return getKind() == ReturnedOwned;
     233                 :   }
     234                 :   
     235               32:   bool isReturnedNotOwned() const {
     236               32:     return getKind() == ReturnedNotOwned;
     237                 :   }
     238                 :   
     239                 :   bool isNonLeakError() const {
     240                 :     Kind k = getKind();
     241                 :     return isError(k) && !isLeak(k);
     242                 :   }
     243                 :   
     244                 :   static RefVal makeOwned(RetEffect::ObjKind o, QualType t,
     245              741:                           unsigned Count = 1) {
     246              741:     return RefVal(Owned, o, Count, 0, t);
     247                 :   }
     248                 :   
     249                 :   static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t,
     250              158:                              unsigned Count = 0) {
     251              158:     return RefVal(NotOwned, o, Count, 0, t);
     252                 :   }
     253                 :   
     254                 :   // Comparison, profiling, and pretty-printing.
     255                 :   
     256             2816:   bool operator==(const RefVal& X) const {
                     2727: branch 0 taken
                       89: branch 1 taken
                     2641: branch 2 taken
                       86: branch 3 taken
                     2641: branch 5 taken
                        0: branch 6 not taken
                     2619: branch 7 taken
                       22: branch 8 taken
     257             2816:     return kind == X.kind && Cnt == X.Cnt && T == X.T && ACnt == X.ACnt;
     258                 :   }
     259                 :   
     260              448:   RefVal operator-(size_t i) const {
     261                 :     return RefVal(getKind(), getObjKind(), getCount() - i,
     262              448:                   getAutoreleaseCount(), getType());
     263                 :   }
     264                 :   
     265              111:   RefVal operator+(size_t i) const {
     266                 :     return RefVal(getKind(), getObjKind(), getCount() + i,
     267              111:                   getAutoreleaseCount(), getType());
     268                 :   }
     269                 :   
     270              819:   RefVal operator^(Kind k) const {
     271                 :     return RefVal(k, getObjKind(), getCount(), getAutoreleaseCount(),
     272              819:                   getType());
     273                 :   }
     274                 :   
     275               66:   RefVal autorelease() const {
     276                 :     return RefVal(getKind(), getObjKind(), getCount(), getAutoreleaseCount()+1,
     277               66:                   getType());
     278                 :   }
     279                 :   
     280             3458:   void Profile(llvm::FoldingSetNodeID& ID) const {
     281             3458:     ID.AddInteger((unsigned) kind);
     282             3458:     ID.AddInteger(Cnt);
     283             3458:     ID.AddInteger(ACnt);
     284             3458:     ID.Add(T);
     285             3458:   }
     286                 :   
     287                 :   void print(llvm::raw_ostream& Out) const;
     288                 : };
     289                 : 
     290                0: void RefVal::print(llvm::raw_ostream& Out) const {
                        0: branch 1 not taken
                        0: branch 2 not taken
     291                0:   if (!T.isNull())
     292                0:     Out << "Tracked Type:" << T.getAsString() << '\n';
     293                 :   
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                        0: branch 12 not taken
                        0: branch 13 not taken
                        0: branch 14 not taken
                        0: branch 15 not taken
     294                0:   switch (getKind()) {
     295                0:     default: assert(false);
     296                 :     case Owned: {
     297                0:       Out << "Owned";
     298                0:       unsigned cnt = getCount();
                        0: branch 0 not taken
                        0: branch 1 not taken
     299                0:       if (cnt) Out << " (+ " << cnt << ")";
     300                0:       break;
     301                 :     }
     302                 :       
     303                 :     case NotOwned: {
     304                0:       Out << "NotOwned";
     305                0:       unsigned cnt = getCount();
                        0: branch 0 not taken
                        0: branch 1 not taken
     306                0:       if (cnt) Out << " (+ " << cnt << ")";
     307                0:       break;
     308                 :     }
     309                 :       
     310                 :     case ReturnedOwned: {
     311                0:       Out << "ReturnedOwned";
     312                0:       unsigned cnt = getCount();
                        0: branch 0 not taken
                        0: branch 1 not taken
     313                0:       if (cnt) Out << " (+ " << cnt << ")";
     314                0:       break;
     315                 :     }
     316                 :       
     317                 :     case ReturnedNotOwned: {
     318                0:       Out << "ReturnedNotOwned";
     319                0:       unsigned cnt = getCount();
                        0: branch 0 not taken
                        0: branch 1 not taken
     320                0:       if (cnt) Out << " (+ " << cnt << ")";
     321                0:       break;
     322                 :     }
     323                 :       
     324                 :     case Released:
     325                0:       Out << "Released";
     326                0:       break;
     327                 :       
     328                 :     case ErrorDeallocGC:
     329                0:       Out << "-dealloc (GC)";
     330                0:       break;
     331                 :       
     332                 :     case ErrorDeallocNotOwned:
     333                0:       Out << "-dealloc (not-owned)";
     334                0:       break;
     335                 :       
     336                 :     case ErrorLeak:
     337                0:       Out << "Leaked";
     338                0:       break;
     339                 :       
     340                 :     case ErrorLeakReturned:
     341                0:       Out << "Leaked (Bad naming)";
     342                0:       break;
     343                 :       
     344                 :     case ErrorGCLeakReturned:
     345                0:       Out << "Leaked (GC-ed at return)";
     346                0:       break;
     347                 :       
     348                 :     case ErrorUseAfterRelease:
     349                0:       Out << "Use-After-Release [ERROR]";
     350                0:       break;
     351                 :       
     352                 :     case ErrorReleaseNotOwned:
     353                0:       Out << "Release of Not-Owned [ERROR]";
     354                0:       break;
     355                 :       
     356                 :     case RefVal::ErrorOverAutorelease:
     357                0:       Out << "Over autoreleased";
     358                0:       break;
     359                 :       
     360                 :     case RefVal::ErrorReturnedNotOwned:
     361                0:       Out << "Non-owned object returned instead of owned";
     362                 :       break;
     363                 :   }
     364                 :   
                        0: branch 0 not taken
                        0: branch 1 not taken
     365                0:   if (ACnt) {
     366                0:     Out << " [ARC +" << ACnt << ']';
     367                 :   }
     368                0: }
     369                 : } //end anonymous namespace
     370                 : 
     371                 : //===----------------------------------------------------------------------===//
     372                 : // RefBindings - State used to track object reference counts.
     373                 : //===----------------------------------------------------------------------===//
     374                 : 
     375                 : typedef llvm::ImmutableMap<SymbolRef, RefVal> RefBindings;
     376                 : 
     377                 : namespace clang {
     378                 :   template<>
     379                 :   struct GRStateTrait<RefBindings> : public GRStatePartialTrait<RefBindings> {
     380            49815:     static void* GDMIndex() {
     381                 :       static int RefBIndex = 0;
     382            49815:       return &RefBIndex;
     383                 :     }
     384                 :   };
     385                 : }
     386                 : 
     387                 : //===----------------------------------------------------------------------===//
     388                 : // Summaries
     389                 : //===----------------------------------------------------------------------===//
     390                 : 
     391                 : namespace {
     392                 : class RetainSummary {
     393                 :   /// Args - an ordered vector of (index, ArgEffect) pairs, where index
     394                 :   ///  specifies the argument (starting from 0).  This can be sparsely
     395                 :   ///  populated; arguments with no entry in Args use 'DefaultArgEffect'.
     396                 :   ArgEffects Args;
     397                 : 
     398                 :   /// DefaultArgEffect - The default ArgEffect to apply to arguments that
     399                 :   ///  do not have an entry in Args.
     400                 :   ArgEffect   DefaultArgEffect;
     401                 : 
     402                 :   /// Receiver - If this summary applies to an Objective-C message expression,
     403                 :   ///  this is the effect applied to the state of the receiver.
     404                 :   ArgEffect   Receiver;
     405                 : 
     406                 :   /// Ret - The effect on the return value.  Used to indicate if the
     407                 :   ///  function/method call returns a new tracked symbol, returns an
     408                 :   ///  alias of one of the arguments in the call, and so on.
     409                 :   RetEffect   Ret;
     410                 : 
     411                 :   /// EndPath - Indicates that execution of this method/function should
     412                 :   ///  terminate the simulation of a path.
     413                 :   bool EndPath;
     414                 : 
     415                 : public:
     416                 :   RetainSummary(ArgEffects A, RetEffect R, ArgEffect defaultEff,
     417            41582:                 ArgEffect ReceiverEff, bool endpath = false)
     418                 :     : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R),
     419            41582:       EndPath(endpath) {}
     420                 : 
     421                 :   /// getArg - Return the argument effect on the argument specified by
     422                 :   ///  idx (starting from 0).
     423             1392:   ArgEffect getArg(unsigned idx) const {
                      337: branch 1 taken
                     1055: branch 2 taken
     424             1392:     if (const ArgEffect *AE = Args.lookup(idx))
     425              337:       return *AE;
     426                 : 
     427             1055:     return DefaultArgEffect;
     428                 :   }
     429                 : 
     430                 :   /// setDefaultArgEffect - Set the default argument effect.
     431               26:   void setDefaultArgEffect(ArgEffect E) {
     432               26:     DefaultArgEffect = E;
     433               26:   }
     434                 : 
     435                 :   /// setArg - Set the argument effect on the argument specified by idx.
     436                 :   void setArgEffect(ArgEffects::Factory& AF, unsigned idx, ArgEffect E) {
     437                 :     Args = AF.Add(Args, idx, E);
     438                 :   }
     439                 : 
     440                 :   /// getRetEffect - Returns the effect on the return value of the call.
     441             2752:   RetEffect getRetEffect() const { return Ret; }
     442                 : 
     443                 :   /// setRetEffect - Set the effect of the return value of the call.
     444               42:   void setRetEffect(RetEffect E) { Ret = E; }
     445                 : 
     446                 :   /// isEndPath - Returns true if executing the given method/function should
     447                 :   ///  terminate the path.
     448             2686:   bool isEndPath() const { return EndPath; }
     449                 : 
     450                 :   /// getReceiverEffect - Returns the effect on the receiver of the call.
     451                 :   ///  This is only meaningful if the summary applies to an ObjCMessageExpr*.
     452              687:   ArgEffect getReceiverEffect() const { return Receiver; }
     453                 : 
     454                 :   /// setReceiverEffect - Set the effect on the receiver of the call.
     455                 :   void setReceiverEffect(ArgEffect E) { Receiver = E; }
     456                 : 
     457                 :   typedef ArgEffects::iterator ExprIterator;
     458                 : 
     459                 :   ExprIterator begin_args() const { return Args.begin(); }
     460                 :   ExprIterator end_args()   const { return Args.end(); }
     461                 : 
     462                 :   static void Profile(llvm::FoldingSetNodeID& ID, ArgEffects A,
     463                 :                       RetEffect RetEff, ArgEffect DefaultEff,
     464                 :                       ArgEffect ReceiverEff, bool EndPath) {
     465                 :     ID.Add(A);
     466                 :     ID.Add(RetEff);
     467                 :     ID.AddInteger((unsigned) DefaultEff);
     468                 :     ID.AddInteger((unsigned) ReceiverEff);
     469                 :     ID.AddInteger((unsigned) EndPath);
     470                 :   }
     471                 : 
     472                 :   void Profile(llvm::FoldingSetNodeID& ID) const {
     473                 :     Profile(ID, Args, Ret, DefaultArgEffect, Receiver, EndPath);
     474                 :   }
     475                 : };
     476                 : } // end anonymous namespace
     477                 : 
     478                 : //===----------------------------------------------------------------------===//
     479                 : // Data structures for constructing summaries.
     480                 : //===----------------------------------------------------------------------===//
     481                 : 
     482                 : namespace {
     483           273664: class ObjCSummaryKey {
     484                 :   IdentifierInfo* II;
     485                 :   Selector S;
     486                 : public:
     487           306085:   ObjCSummaryKey(IdentifierInfo* ii, Selector s)
     488           306085:     : II(ii), S(s) {}
     489                 : 
     490             2191:   ObjCSummaryKey(const ObjCInterfaceDecl* d, Selector s)
                     1538: branch 0 taken
                      653: branch 1 taken
     491             2191:     : II(d ? d->getIdentifier() : 0), S(s) {}
     492                 : 
     493              364:   ObjCSummaryKey(const ObjCInterfaceDecl* d, IdentifierInfo *ii, Selector s)
                      267: branch 0 taken
                       97: branch 1 taken
     494              364:     : II(d ? d->getIdentifier() : ii), S(s) {}
     495                 : 
     496            25755:   ObjCSummaryKey(Selector s)
     497            25755:     : II(0), S(s) {}
     498                 : 
     499          2092431:   IdentifierInfo* getIdentifier() const { return II; }
     500           836399:   Selector getSelector() const { return S; }
     501                 : };
     502                 : }
     503                 : 
     504                 : namespace llvm {
     505                 : template <> struct DenseMapInfo<ObjCSummaryKey> {
     506           168175:   static inline ObjCSummaryKey getEmptyKey() {
     507                 :     return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
     508           168175:                           DenseMapInfo<Selector>::getEmptyKey());
     509                 :   }
     510                 : 
     511            88315:   static inline ObjCSummaryKey getTombstoneKey() {
     512                 :     return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(),
     513            88315:                           DenseMapInfo<Selector>::getTombstoneKey());
     514                 :   }
     515                 : 
     516            78295:   static unsigned getHashValue(const ObjCSummaryKey &V) {
     517                 :     return (DenseMapInfo<IdentifierInfo*>::getHashValue(V.getIdentifier())
     518                 :             & 0x88888888)
     519                 :         | (DenseMapInfo<Selector>::getHashValue(V.getSelector())
     520            78295:             & 0x55555555);
     521                 :   }
     522                 : 
     523          1007068:   static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
     524                 :     return DenseMapInfo<IdentifierInfo*>::isEqual(LHS.getIdentifier(),
     525                 :                                                   RHS.getIdentifier()) &&
     526                 :            DenseMapInfo<Selector>::isEqual(LHS.getSelector(),
                   379052: branch 3 taken
                   628016: branch 4 taken
                   351959: branch 8 taken
                    27093: branch 9 taken
     527          1007068:                                            RHS.getSelector());
     528                 :   }
     529                 : 
     530                 : };
     531                 : template <>
     532                 : struct isPodLike<ObjCSummaryKey> { static const bool value = true; };
     533                 : } // end llvm namespace
     534                 : 
     535                 : namespace {
     536             4276: class ObjCSummaryCache {
     537                 :   typedef llvm::DenseMap<ObjCSummaryKey, RetainSummary*> MapTy;
     538                 :   MapTy M;
     539                 : public:
     540             4276:   ObjCSummaryCache() {}
     541                 : 
     542                 :   RetainSummary* find(const ObjCInterfaceDecl* D, IdentifierInfo *ClsName,
     543             1277:                 Selector S) {
     544                 :     // Lookup the method using the decl for the class @interface.  If we
     545                 :     // have no decl, lookup using the class name.
                      856: branch 0 taken
                      421: branch 1 taken
     546             1277:     return D ? find(D, S) : find(ClsName, S);
     547                 :   }
     548                 : 
     549              856:   RetainSummary* find(const ObjCInterfaceDecl* D, Selector S) {
     550                 :     // Do a lookup with the (D,S) pair.  If we find a match return
     551                 :     // the iterator.
     552              856:     ObjCSummaryKey K(D, S);
     553              856:     MapTy::iterator I = M.find(K);
     554                 : 
                      657: branch 3 taken
                      199: branch 4 taken
                        0: branch 5 not taken
                      657: branch 6 taken
                      199: branch 7 taken
                      657: branch 8 taken
     555              856:     if (I != M.end() || !D)
     556              199:       return I->second;
     557                 : 
     558                 :     // Walk the super chain.  If we find a hit with a parent, we'll end
     559                 :     // up returning that summary.  We actually allow that key (null,S), as
     560                 :     // we cache summaries for the null ObjCInterfaceDecl* to allow us to
     561                 :     // generate initial summaries without having to worry about NSObject
     562                 :     // being declared.
     563                 :     // FIXME: We may change this at some point.
     564             1335:     for (ObjCInterfaceDecl* C=D->getSuperClass() ;; C=C->getSuperClass()) {
                      945: branch 5 taken
                      390: branch 6 taken
     565             1335:       if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
     566              390:         break;
     567                 : 
                      267: branch 0 taken
                      678: branch 1 taken
     568              945:       if (!C)
     569              267:         return NULL;
     570                 :     }
     571                 : 
     572                 :     // Cache the summary with original key to make the next lookup faster
     573                 :     // and return the iterator.
     574              390:     RetainSummary *Summ = I->second;
     575              390:     M[K] = Summ;
     576              390:     return Summ;
     577                 :   }
     578                 : 
     579                 : 
     580                 :   RetainSummary* find(Expr* Receiver, Selector S) {
     581                 :     return find(getReceiverDecl(Receiver), S);
     582                 :   }
     583                 : 
     584              421:   RetainSummary* find(IdentifierInfo* II, Selector S) {
     585                 :     // FIXME: Class method lookup.  Right now we dont' have a good way
     586                 :     // of going between IdentifierInfo* and the class hierarchy.
     587              421:     MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
     588                 : 
                       99: branch 3 taken
                      322: branch 4 taken
     589              421:     if (I == M.end())
     590               99:       I = M.find(ObjCSummaryKey(S));
     591                 : 
                       97: branch 3 taken
                      324: branch 4 taken
     592              421:     return I == M.end() ? NULL : I->second;
     593                 :   }
     594                 : 
     595                 :   const ObjCInterfaceDecl* getReceiverDecl(Expr* E) {
     596                 :     if (const ObjCObjectPointerType* PT =
     597                 :         E->getType()->getAs<ObjCObjectPointerType>())
     598                 :       return PT->getInterfaceDecl();
     599                 : 
     600                 :     return NULL;
     601                 :   }
     602                 : 
     603                 :   RetainSummary*& operator[](ObjCMessageExpr* ME) {
     604                 : 
     605                 :     Selector S = ME->getSelector();
     606                 : 
     607                 :     if (Expr* Receiver = ME->getReceiver()) {
     608                 :       const ObjCInterfaceDecl* OD = getReceiverDecl(Receiver);
     609                 :       return OD ? M[ObjCSummaryKey(OD->getIdentifier(), S)] : M[S];
     610                 :     }
     611                 : 
     612                 :     return M[ObjCSummaryKey(ME->getClassName(), S)];
     613                 :   }
     614                 : 
     615            49538:   RetainSummary*& operator[](ObjCSummaryKey K) {
     616            49538:     return M[K];
     617                 :   }
     618                 : 
     619            25656:   RetainSummary*& operator[](Selector S) {
     620            25656:     return M[ ObjCSummaryKey(S) ];
     621                 :   }
     622                 : };
     623                 : } // end anonymous namespace
     624                 : 
     625                 : //===----------------------------------------------------------------------===//
     626                 : // Data structures for managing collections of summaries.
     627                 : //===----------------------------------------------------------------------===//
     628                 : 
     629                 : namespace {
     630                 : class RetainSummaryManager {
     631                 : 
     632                 :   //==-----------------------------------------------------------------==//
     633                 :   //  Typedefs.
     634                 :   //==-----------------------------------------------------------------==//
     635                 : 
     636                 :   typedef llvm::DenseMap<FunctionDecl*, RetainSummary*>
     637                 :           FuncSummariesTy;
     638                 : 
     639                 :   typedef ObjCSummaryCache ObjCMethodSummariesTy;
     640                 : 
     641                 :   //==-----------------------------------------------------------------==//
     642                 :   //  Data.
     643                 :   //==-----------------------------------------------------------------==//
     644                 : 
     645                 :   /// Ctx - The ASTContext object for the analyzed ASTs.
     646                 :   ASTContext& Ctx;
     647                 : 
     648                 :   /// CFDictionaryCreateII - An IdentifierInfo* representing the indentifier
     649                 :   ///  "CFDictionaryCreate".
     650                 :   IdentifierInfo* CFDictionaryCreateII;
     651                 : 
     652                 :   /// GCEnabled - Records whether or not the analyzed code runs in GC mode.
     653                 :   const bool GCEnabled;
     654                 : 
     655                 :   /// FuncSummaries - A map from FunctionDecls to summaries.
     656                 :   FuncSummariesTy FuncSummaries;
     657                 : 
     658                 :   /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
     659                 :   ///  to summaries.
     660                 :   ObjCMethodSummariesTy ObjCClassMethodSummaries;
     661                 : 
     662                 :   /// ObjCMethodSummaries - A map from selectors to summaries.
     663                 :   ObjCMethodSummariesTy ObjCMethodSummaries;
     664                 : 
     665                 :   /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
     666                 :   ///  and all other data used by the checker.
     667                 :   llvm::BumpPtrAllocator BPAlloc;
     668                 : 
     669                 :   /// AF - A factory for ArgEffects objects.
     670                 :   ArgEffects::Factory AF;
     671                 : 
     672                 :   /// ScratchArgs - A holding buffer for construct ArgEffects.
     673                 :   ArgEffects ScratchArgs;
     674                 : 
     675                 :   /// ObjCAllocRetE - Default return effect for methods returning Objective-C
     676                 :   ///  objects.
     677                 :   RetEffect ObjCAllocRetE;
     678                 : 
     679                 :   /// ObjCInitRetE - Default return effect for init methods returning
     680                 :   ///   Objective-C objects.
     681                 :   RetEffect ObjCInitRetE;
     682                 : 
     683                 :   RetainSummary DefaultSummary;
     684                 :   RetainSummary* StopSummary;
     685                 : 
     686                 :   //==-----------------------------------------------------------------==//
     687                 :   //  Methods.
     688                 :   //==-----------------------------------------------------------------==//
     689                 : 
     690                 :   /// getArgEffects - Returns a persistent ArgEffects object based on the
     691                 :   ///  data in ScratchArgs.
     692                 :   ArgEffects getArgEffects();
     693                 : 
     694                 :   enum UnaryFuncKind { cfretain, cfrelease, cfmakecollectable };
     695                 : 
     696                 : public:
     697              212:   RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
     698                 : 
     699              699:   RetainSummary *getDefaultSummary() {
     700              699:     RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
                      699: branch 1 taken
                        0: branch 2 not taken
     701              699:     return new (Summ) RetainSummary(DefaultSummary);
     702                 :   }
     703                 : 
     704                 :   RetainSummary* getUnarySummary(const FunctionType* FT, UnaryFuncKind func);
     705                 : 
     706                 :   RetainSummary* getCFSummaryCreateRule(FunctionDecl* FD);
     707                 :   RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);
     708                 :   RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, StringRef FName);
     709                 : 
     710                 :   RetainSummary* getPersistentSummary(ArgEffects AE, RetEffect RetEff,
     711                 :                                       ArgEffect ReceiverEff = DoNothing,
     712                 :                                       ArgEffect DefaultEff = MayEscape,
     713                 :                                       bool isEndPath = false);
     714                 : 
     715                 :   RetainSummary* getPersistentSummary(RetEffect RE,
     716                 :                                       ArgEffect ReceiverEff = DoNothing,
     717            35168:                                       ArgEffect DefaultEff = MayEscape) {
     718            35168:     return getPersistentSummary(getArgEffects(), RE, ReceiverEff, DefaultEff);
     719                 :   }
     720                 : 
     721              104:   RetainSummary *getPersistentStopSummary() {
                        1: branch 0 taken
                      103: branch 1 taken
     722              104:     if (StopSummary)
     723                1:       return StopSummary;
     724                 : 
     725                 :     StopSummary = getPersistentSummary(RetEffect::MakeNoRet(),
     726              103:                                        StopTracking, StopTracking);
     727                 : 
     728              103:     return StopSummary;
     729                 :   }
     730                 : 
     731                 :   RetainSummary *getInitMethodSummary(QualType RetTy);
     732                 : 
     733                 :   void InitializeClassMethodSummaries();
     734                 :   void InitializeMethodSummaries();
     735                 : private:
     736                 : 
     737                 :   void addClsMethSummary(IdentifierInfo* ClsII, Selector S,
     738                 :                          RetainSummary* Summ) {
     739                 :     ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
     740                 :   }
     741                 : 
     742             6414:   void addNSObjectClsMethSummary(Selector S, RetainSummary *Summ) {
     743             6414:     ObjCClassMethodSummaries[S] = Summ;
     744             6414:   }
     745                 : 
     746            19242:   void addNSObjectMethSummary(Selector S, RetainSummary *Summ) {
     747            19242:     ObjCMethodSummaries[S] = Summ;
     748            19242:   }
     749                 : 
     750                 :   void addClassMethSummary(const char* Cls, const char* nullaryName,
     751            12828:                            RetainSummary *Summ) {
     752            12828:     IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
     753            12828:     Selector S = GetNullarySelector(nullaryName, Ctx);
     754            12828:     ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
     755            12828:   }
     756                 : 
     757                 :   void addInstMethSummary(const char* Cls, const char* nullaryName,
     758             2138:                           RetainSummary *Summ) {
     759             2138:     IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
     760             2138:     Selector S = GetNullarySelector(nullaryName, Ctx);
     761             2138:     ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
     762             2138:   }
     763                 : 
     764            34208:   Selector generateSelector(va_list argp) {
     765            34208:     llvm::SmallVector<IdentifierInfo*, 10> II;
     766                 : 
                   104762: branch 0 taken
                    34208: branch 1 taken
     767           243732:     while (const char* s = va_arg(argp, const char*))
     768           104762:       II.push_back(&Ctx.Idents.get(s));
     769                 : 
     770            34208:     return Ctx.Selectors.getSelector(II.size(), &II[0]);
     771                 :   }
     772                 : 
     773                 :   void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy& Summaries,
     774            34208:                         RetainSummary* Summ, va_list argp) {
     775            34208:     Selector S = generateSelector(argp);
     776            34208:     Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
     777            34208:   }
     778                 : 
     779            10690:   void addInstMethSummary(const char* Cls, RetainSummary* Summ, ...) {
     780                 :     va_list argp;
     781            10690:     va_start(argp, Summ);
     782            10690:     addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp);
     783            10690:     va_end(argp);
     784            10690:   }
     785                 : 
     786             4276:   void addClsMethSummary(const char* Cls, RetainSummary* Summ, ...) {
     787                 :     va_list argp;
     788             4276:     va_start(argp, Summ);
     789             4276:     addMethodSummary(&Ctx.Idents.get(Cls),ObjCClassMethodSummaries, Summ, argp);
     790             4276:     va_end(argp);
     791             4276:   }
     792                 : 
     793            14966:   void addClsMethSummary(IdentifierInfo *II, RetainSummary* Summ, ...) {
     794                 :     va_list argp;
     795            14966:     va_start(argp, Summ);
     796            14966:     addMethodSummary(II, ObjCClassMethodSummaries, Summ, argp);
     797            14966:     va_end(argp);
     798            14966:   }
     799                 : 
     800             4276:   void addPanicSummary(const char* Cls, ...) {
     801                 :     RetainSummary* Summ = getPersistentSummary(AF.GetEmptyMap(),
     802                 :                                                RetEffect::MakeNoRet(),
     803             4276:                                                DoNothing,  DoNothing, true);
     804                 :     va_list argp;
     805             4276:     va_start (argp, Cls);
     806             4276:     addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp);
     807             4276:     va_end(argp);
     808             4276:   }
     809                 : 
     810                 : public:
     811                 : 
     812             2138:   RetainSummaryManager(ASTContext& ctx, bool gcenabled)
     813                 :    : Ctx(ctx),
     814                 :      CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
     815                 :      GCEnabled(gcenabled), AF(BPAlloc), ScratchArgs(AF.GetEmptyMap()),
     816                 :      ObjCAllocRetE(gcenabled ? RetEffect::MakeGCNotOwned()
     817                 :                              : RetEffect::MakeOwned(RetEffect::ObjC, true)),
     818                 :      ObjCInitRetE(gcenabled ? RetEffect::MakeGCNotOwned()
     819                 :                             : RetEffect::MakeOwnedWhenTrackedReceiver()),
     820                 :      DefaultSummary(AF.GetEmptyMap() /* per-argument effects (none) */,
     821                 :                     RetEffect::MakeNoRet() /* return effect */,
     822                 :                     MayEscape, /* default argument effect */
     823                 :                     DoNothing /* receiver effect */),
                      238: branch 8 taken
                     1900: branch 9 taken
                      238: branch 12 taken
                     1900: branch 13 taken
     824             2138:      StopSummary(0) {
     825                 : 
     826             2138:     InitializeClassMethodSummaries();
     827             2138:     InitializeMethodSummaries();
     828             2138:   }
     829                 : 
     830                 :   ~RetainSummaryManager();
     831                 : 
     832                 :   RetainSummary* getSummary(FunctionDecl* FD);
     833                 : 
     834                 :   RetainSummary *getInstanceMethodSummary(const ObjCMessageExpr *ME,
     835                 :                                           const GRState *state,
     836                 :                                           const LocationContext *LC);
     837                 :   
     838                 :   RetainSummary* getInstanceMethodSummary(const ObjCMessageExpr* ME,
     839              846:                                           const ObjCInterfaceDecl* ID) {
     840                 :     return getInstanceMethodSummary(ME->getSelector(), ME->getClassName(),
     841              846:                             ID, ME->getMethodDecl(), ME->getType());
     842                 :   }
     843                 : 
     844                 :   RetainSummary* getInstanceMethodSummary(Selector S, IdentifierInfo *ClsName,
     845                 :                                           const ObjCInterfaceDecl* ID,
     846                 :                                           const ObjCMethodDecl *MD,
     847                 :                                           QualType RetTy);
     848                 : 
     849                 :   RetainSummary *getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
     850                 :                                        const ObjCInterfaceDecl *ID,
     851                 :                                        const ObjCMethodDecl *MD,
     852                 :                                        QualType RetTy);
     853                 : 
     854              365:   RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME) {
     855                 :     return getClassMethodSummary(ME->getSelector(), ME->getClassName(),
     856                 :                                  ME->getClassInfo().first,
     857              365:                                  ME->getMethodDecl(), ME->getType());
     858                 :   }
     859                 : 
     860                 :   /// getMethodSummary - This version of getMethodSummary is used to query
     861                 :   ///  the summary for the current method being analyzed.
     862               66:   RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {
     863                 :     // FIXME: Eventually this should be unneeded.
     864               66:     const ObjCInterfaceDecl *ID = MD->getClassInterface();
     865               66:     Selector S = MD->getSelector();
     866               66:     IdentifierInfo *ClsName = ID->getIdentifier();
     867               66:     QualType ResultTy = MD->getResultType();
     868                 : 
     869                 :     // Resolve the method decl last.
                       64: branch 1 taken
                        2: branch 2 taken
     870               66:     if (const ObjCMethodDecl *InterfaceMD = ResolveToInterfaceMethodDecl(MD))
     871               64:       MD = InterfaceMD;
     872                 : 
                       54: branch 1 taken
                       12: branch 2 taken
     873               66:     if (MD->isInstanceMethod())
     874               54:       return getInstanceMethodSummary(S, ClsName, ID, MD, ResultTy);
     875                 :     else
     876               12:       return getClassMethodSummary(S, ClsName, ID, MD, ResultTy);
     877                 :   }
     878                 : 
     879                 :   RetainSummary* getCommonMethodSummary(const ObjCMethodDecl* MD,
     880                 :                                         Selector S, QualType RetTy);
     881                 : 
     882                 :   void updateSummaryFromAnnotations(RetainSummary &Summ,
     883                 :                                     const ObjCMethodDecl *MD);
     884                 : 
     885                 :   void updateSummaryFromAnnotations(RetainSummary &Summ,
     886                 :                                     const FunctionDecl *FD);
     887                 : 
     888            10710:   bool isGCEnabled() const { return GCEnabled; }
     889                 : 
     890               26:   RetainSummary *copySummary(RetainSummary *OldSumm) {
     891               26:     RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
                       26: branch 1 taken
                        0: branch 2 not taken
     892               26:     new (Summ) RetainSummary(*OldSumm);
     893               26:     return Summ;
     894                 :   }
     895                 : };
     896                 : 
     897                 : } // end anonymous namespace
     898                 : 
     899                 : //===----------------------------------------------------------------------===//
     900                 : // Implementation of checker data structures.
     901                 : //===----------------------------------------------------------------------===//
     902                 : 
     903             2138: RetainSummaryManager::~RetainSummaryManager() {}
     904                 : 
     905            35168: ArgEffects RetainSummaryManager::getArgEffects() {
     906            35168:   ArgEffects AE = ScratchArgs;
     907            35168:   ScratchArgs = AF.GetEmptyMap();
     908                 :   return AE;
     909                 : }
     910                 : 
     911                 : RetainSummary*
     912                 : RetainSummaryManager::getPersistentSummary(ArgEffects AE, RetEffect RetEff,
     913                 :                                            ArgEffect ReceiverEff,
     914                 :                                            ArgEffect DefaultEff,
     915            39444:                                            bool isEndPath) {
     916                 :   // Create the summary and return it.
     917            39444:   RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
                    39444: branch 1 taken
                        0: branch 2 not taken
     918            39444:   new (Summ) RetainSummary(AE, RetEff, DefaultEff, ReceiverEff, isEndPath);
     919            39444:   return Summ;
     920                 : }
     921                 : 
     922                 : //===----------------------------------------------------------------------===//
     923                 : // Summary creation for functions (largely uses of Core Foundation).
     924                 : //===----------------------------------------------------------------------===//
     925                 : 
     926              343: static bool isRetain(FunctionDecl* FD, StringRef FName) {
     927              343:   return FName.endswith("Retain");
     928                 : }
     929                 : 
     930              217: static bool isRelease(FunctionDecl* FD, StringRef FName) {
     931              217:   return FName.endswith("Release");
     932                 : }
     933                 : 
     934             1464: RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
     935                 :   // Look up a summary in our cache of FunctionDecls -> Summaries.
     936             1464:   FuncSummariesTy::iterator I = FuncSummaries.find(FD);
                      224: branch 3 taken
                     1240: branch 4 taken
     937             1464:   if (I != FuncSummaries.end())
     938              224:     return I->second;
     939                 : 
     940                 :   // No summary?  Generate one.
     941             1240:   RetainSummary *S = 0;
     942                 : 
     943                 :   do {
     944                 :     // We generate "stop" summaries for implicitly defined functions.
                       54: branch 1 taken
                     1186: branch 2 taken
     945             1240:     if (FD->isImplicit()) {
     946               54:       S = getPersistentStopSummary();
     947               54:       break;
     948                 :     }
     949                 : 
     950                 :     // [PR 3337] Use 'getAs<FunctionType>' to strip away any typedefs on the
     951                 :     // function's type.
     952             1186:     const FunctionType* FT = FD->getType()->getAs<FunctionType>();
     953             1186:     const IdentifierInfo *II = FD->getIdentifier();
                        0: branch 0 not taken
                     1186: branch 1 taken
     954             1186:     if (!II)
     955                0:       break;
     956                 : 
     957             1186:     StringRef FName = II->getName();
     958                 : 
     959                 :     // Strip away preceding '_'.  Doing this here will effect all the checks
     960                 :     // down below.
     961             1186:     FName = FName.substr(FName.find_first_not_of('_'));
     962                 : 
     963                 :     // Inspect the result type.
     964             1186:     QualType RetTy = FT->getResultType();
     965                 : 
     966                 :     // FIXME: This should all be refactored into a chain of "summary lookup"
     967                 :     //  filters.
                        0: branch 1 not taken
                     1186: branch 2 taken
     968             1186:     assert(ScratchArgs.isEmpty());
     969                 : 
                        2: branch 2 taken
                     1184: branch 3 taken
     970             1186:     if (FName == "pthread_create") {
     971                 :       // Part of: <rdar://problem/7299394>.  This will be addressed
     972                 :       // better with IPA.
     973                2:       S = getPersistentStopSummary();
                       16: branch 2 taken
                     1168: branch 3 taken
     974             1184:     } else if (FName == "NSMakeCollectable") {
     975                 :       // Handle: id NSMakeCollectable(CFTypeRef)
     976                 :       S = (RetTy->isObjCIdType())
     977                 :           ? getUnarySummary(FT, cfmakecollectable)
                       16: branch 2 taken
                        0: branch 3 not taken
     978               16:           : getPersistentStopSummary();
                     1166: branch 2 taken
                        2: branch 3 taken
                     1164: branch 6 taken
                        2: branch 7 taken
                     1162: branch 10 taken
                        2: branch 11 taken
                     1160: branch 14 taken
                        2: branch 15 taken
                        2: branch 18 taken
                     1158: branch 19 taken
                       10: branch 20 taken
                     1158: branch 21 taken
     979             1168:     } else if (FName == "IOBSDNameMatching" ||
     980                 :                FName == "IOServiceMatching" ||
     981                 :                FName == "IOServiceNameMatching" ||
     982                 :                FName == "IORegistryEntryIDMatching" ||
     983                 :                FName == "IOOpenFirmwarePathMatching") {
     984                 :       // Part of <rdar://problem/6961230>. (IOKit)
     985                 :       // This should be addressed using a API table.
     986                 :       S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
     987               10:                                DoNothing, DoNothing);
                     1156: branch 2 taken
                        2: branch 3 taken
                        2: branch 6 taken
                     1154: branch 7 taken
                        4: branch 8 taken
                     1154: branch 9 taken
     988             1158:     } else if (FName == "IOServiceGetMatchingService" ||
     989                 :                FName == "IOServiceGetMatchingServices") {
     990                 :       // FIXES: <rdar://problem/6326900>
     991                 :       // This should be addressed using a API table.  This strcmp is also
     992                 :       // a little gross, but there is no need to super optimize here.
     993                4:       ScratchArgs = AF.Add(ScratchArgs, 1, DecRef);
     994                4:       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
                     1152: branch 2 taken
                        2: branch 3 taken
                        2: branch 6 taken
                     1150: branch 7 taken
                        4: branch 8 taken
                     1150: branch 9 taken
     995             1154:     } else if (FName == "IOServiceAddNotification" ||
     996                 :                FName == "IOServiceAddMatchingNotification") {
     997                 :       // Part of <rdar://problem/6961230>. (IOKit)
     998                 :       // This should be addressed using a API table.
     999                4:       ScratchArgs = AF.Add(ScratchArgs, 2, DecRef);
    1000                4:       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
                        2: branch 2 taken
                     1148: branch 3 taken
    1001             1150:     } else if (FName == "CVPixelBufferCreateWithBytes") {
    1002                 :       // FIXES: <rdar://problem/7283567>
    1003                 :       // Eventually this can be improved by recognizing that the pixel
    1004                 :       // buffer passed to CVPixelBufferCreateWithBytes is released via
    1005                 :       // a callback and doing full IPA to make sure this is done correctly.
    1006                 :       // FIXME: This function has an out parameter that returns an
    1007                 :       // allocated object.
    1008                2:       ScratchArgs = AF.Add(ScratchArgs, 7, StopTracking);
    1009                2:       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
                        2: branch 2 taken
                     1146: branch 3 taken
    1010             1148:     } else if (FName == "CGBitmapContextCreateWithData") {
    1011                 :       // FIXES: <rdar://problem/7358899>
    1012                 :       // Eventually this can be improved by recognizing that 'releaseInfo'
    1013                 :       // passed to CGBitmapContextCreateWithData is released via
    1014                 :       // a callback and doing full IPA to make sure this is done correctly.
    1015                2:       ScratchArgs = AF.Add(ScratchArgs, 8, StopTracking);
    1016                 :       S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true),
    1017                2:                                DoNothing, DoNothing);
                        2: branch 2 taken
                     1144: branch 3 taken
    1018             1146:     } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
    1019                 :       // FIXES: <rdar://problem/7283567>
    1020                 :       // Eventually this can be improved by recognizing that the pixel
    1021                 :       // buffer passed to CVPixelBufferCreateWithPlanarBytes is released
    1022                 :       // via a callback and doing full IPA to make sure this is done
    1023                 :       // correctly.
    1024                2:       ScratchArgs = AF.Add(ScratchArgs, 12, StopTracking);
    1025                2:       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
    1026                 :     }
    1027                 : 
    1028                 :     // Did we get a summary?
                       42: branch 0 taken
                     1144: branch 1 taken
    1029             1186:     if (S)
    1030               42:       break;
    1031                 : 
    1032                 :     // Enable this code once the semantics of NSDeallocateObject are resolved
    1033                 :     // for GC.  <rdar://problem/6619988>
    1034                 : #if 0
    1035                 :     // Handle: NSDeallocateObject(id anObject);
    1036                 :     // This method does allow 'nil' (although we don't check it now).
    1037                 :     if (strcmp(FName, "NSDeallocateObject") == 0) {
    1038                 :       return RetTy == Ctx.VoidTy
    1039                 :         ? getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, Dealloc)
    1040                 :         : getPersistentStopSummary();
    1041                 :     }
    1042                 : #endif
    1043                 : 
                      481: branch 2 taken
                      663: branch 3 taken
    1044             1144:     if (RetTy->isPointerType()) {
    1045                 :       // For CoreFoundation ('CF') types.
                      319: branch 2 taken
                      162: branch 3 taken
    1046              481:       if (cocoa::isRefType(RetTy, "CF", FName)) {
                       62: branch 1 taken
                      257: branch 2 taken
    1047              319:         if (isRetain(FD, FName))
    1048               62:           S = getUnarySummary(FT, cfretain);
                       34: branch 2 taken
                      223: branch 3 taken
    1049              257:         else if (FName.find("MakeCollectable") != StringRef::npos)
    1050               34:           S = getUnarySummary(FT, cfmakecollectable);
    1051                 :         else
    1052              223:           S = getCFCreateGetRuleSummary(FD, FName);
    1053                 : 
    1054              319:         break;
    1055                 :       }
    1056                 : 
    1057                 :       // For CoreGraphics ('CG') types.
                       24: branch 2 taken
                      138: branch 3 taken
    1058              162:       if (cocoa::isRefType(RetTy, "CG", FName)) {
                        8: branch 1 taken
                       16: branch 2 taken
    1059               24:         if (isRetain(FD, FName))
    1060                8:           S = getUnarySummary(FT, cfretain);
    1061                 :         else
    1062               16:           S = getCFCreateGetRuleSummary(FD, FName);
    1063                 : 
    1064               24:         break;
    1065                 :       }
    1066                 : 
    1067                 :       // For the Disk Arbitration API (DiskArbitration/DADisk.h)
                      132: branch 3 taken
                        6: branch 4 taken
                      130: branch 8 taken
                        2: branch 9 taken
                        2: branch 13 taken
                      128: branch 14 taken
                       10: branch 15 taken
                      128: branch 16 taken
    1068              138:       if (cocoa::isRefType(RetTy, "DADisk") ||
    1069                 :           cocoa::isRefType(RetTy, "DADissenter") ||
    1070                 :           cocoa::isRefType(RetTy, "DASessionRef")) {
    1071               10:         S = getCFCreateGetRuleSummary(FD, FName);
    1072               10:         break;
    1073                 :       }
    1074                 : 
    1075              128:       break;
    1076                 :     }
    1077                 : 
    1078                 :     // Check for release functions, the only kind of functions that we care
    1079                 :     // about that don't return a pointer type.
                      217: branch 1 taken
                      446: branch 2 taken
                       10: branch 4 taken
                      207: branch 5 taken
                       10: branch 7 taken
                        0: branch 8 not taken
                      217: branch 9 taken
                      446: branch 10 taken
    1080              663:     if (FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) {
    1081                 :       // Test for 'CGCF'.
                        0: branch 2 not taken
                      217: branch 3 taken
    1082              217:       FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);
    1083                 : 
                       80: branch 1 taken
                      137: branch 2 taken
    1084              217:       if (isRelease(FD, FName))
    1085               80:         S = getUnarySummary(FT, cfrelease);
    1086                 :       else {
                        0: branch 1 not taken
                      137: branch 2 taken
    1087              137:         assert (ScratchArgs.isEmpty());
    1088                 :         // Remaining CoreFoundation and CoreGraphics functions.
    1089                 :         // We use to assume that they all strictly followed the ownership idiom
    1090                 :         // and that ownership cannot be transferred.  While this is technically
    1091                 :         // correct, many methods allow a tracked object to escape.  For example:
    1092                 :         //
    1093                 :         //   CFMutableDictionaryRef x = CFDictionaryCreateMutable(...);
    1094                 :         //   CFDictionaryAddValue(y, key, x);
    1095                 :         //   CFRelease(x);
    1096                 :         //   ... it is okay to use 'x' since 'y' has a reference to it
    1097                 :         //
    1098                 :         // We handle this and similar cases with the follow heuristic.  If the
    1099                 :         // function name contains "InsertValue", "SetValue", "AddValue",
    1100                 :         // "AppendValue", or "SetAttribute", then we assume that arguments may
    1101                 :         // "escape."  This means that something else holds on to the object,
    1102                 :         // allowing it be used even after its local retain count drops to 0.
    1103                 :         ArgEffect E = (StrInStrNoCase(FName, "InsertValue") != StringRef::npos||
    1104                 :                        StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
    1105                 :                        StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
    1106                 :                        StrInStrNoCase(FName, "AppendValue") != StringRef::npos||
    1107                 :                        StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)
                      137: branch 2 taken
                        0: branch 3 not taken
                      135: branch 6 taken
                        2: branch 7 taken
                      135: branch 10 taken
                        0: branch 11 not taken
                      131: branch 14 taken
                        4: branch 15 taken
                        2: branch 18 taken
                      129: branch 19 taken
    1108              137:                       ? MayEscape : DoNothing;
    1109                 : 
    1110              137:         S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E);
    1111                 :       }
    1112                 :     }
    1113                 :   }
    1114                 :   while (0);
    1115                 : 
                      574: branch 0 taken
                      666: branch 1 taken
    1116             1240:   if (!S)
    1117              574:     S = getDefaultSummary();
    1118                 : 
    1119                 :   // Annotations override defaults.
                        0: branch 0 not taken
                     1240: branch 1 taken
    1120             1240:   assert(S);
    1121             1240:   updateSummaryFromAnnotations(*S, FD);
    1122                 : 
    1123             1240:   FuncSummaries[FD] = S;
    1124             1240:   return S;
    1125                 : }
    1126                 : 
    1127                 : RetainSummary*
    1128                 : RetainSummaryManager::getCFCreateGetRuleSummary(FunctionDecl* FD,
    1129              249:                                                 StringRef FName) {
    1130                 : 
                       32: branch 2 taken
                      217: branch 3 taken
                        4: branch 6 taken
                       28: branch 7 taken
                      221: branch 8 taken
                       28: branch 9 taken
    1131              249:   if (FName.find("Create") != StringRef::npos ||
    1132                 :       FName.find("Copy") != StringRef::npos)
    1133              221:     return getCFSummaryCreateRule(FD);
    1134                 : 
                       10: branch 2 taken
                       18: branch 3 taken
    1135               28:   if (FName.find("Get") != StringRef::npos)
    1136               10:     return getCFSummaryGetRule(FD);
    1137                 : 
    1138               18:   return getDefaultSummary();
    1139                 : }
    1140                 : 
    1141                 : RetainSummary*
    1142                 : RetainSummaryManager::getUnarySummary(const FunctionType* FT,
    1143              200:                                       UnaryFuncKind func) {
    1144                 : 
    1145                 :   // Sanity check that this is *really* a unary function.  This can
    1146                 :   // happen if people do weird things.
    1147              200:   const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);
                      200: branch 0 taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                      200: branch 4 taken
                        0: branch 5 not taken
                      200: branch 6 taken
    1148              200:   if (!FTP || FTP->getNumArgs() != 1)
    1149                0:     return getPersistentStopSummary();
    1150                 : 
                        0: branch 1 not taken
                      200: branch 2 taken
    1151              200:   assert (ScratchArgs.isEmpty());
    1152                 : 
                       70: branch 0 taken
                       80: branch 1 taken
                       50: branch 2 taken
                        0: branch 3 not taken
    1153              200:   switch (func) {
    1154                 :     case cfretain: {
    1155               70:       ScratchArgs = AF.Add(ScratchArgs, 0, IncRef);
    1156                 :       return getPersistentSummary(RetEffect::MakeAlias(0),
    1157               70:                                   DoNothing, DoNothing);
    1158                 :     }
    1159                 : 
    1160                 :     case cfrelease: {
    1161               80:       ScratchArgs = AF.Add(ScratchArgs, 0, DecRef);
    1162                 :       return getPersistentSummary(RetEffect::MakeNoRet(),
    1163               80:                                   DoNothing, DoNothing);
    1164                 :     }
    1165                 : 
    1166                 :     case cfmakecollectable: {
    1167               50:       ScratchArgs = AF.Add(ScratchArgs, 0, MakeCollectable);
    1168               50:       return getPersistentSummary(RetEffect::MakeAlias(0),DoNothing, DoNothing);
    1169                 :     }
    1170                 : 
    1171                 :     default:
    1172                0:       assert (false && "Not a supported unary function.");
    1173                 :       return getDefaultSummary();
    1174                 :   }
    1175                 : }
    1176                 : 
    1177              221: RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
                        0: branch 1 not taken
                      221: branch 2 taken
    1178              221:   assert (ScratchArgs.isEmpty());
    1179                 : 
                        4: branch 1 taken
                      217: branch 2 taken
    1180              221:   if (FD->getIdentifier() == CFDictionaryCreateII) {
    1181                4:     ScratchArgs = AF.Add(ScratchArgs, 1, DoNothingByRef);
    1182                4:     ScratchArgs = AF.Add(ScratchArgs, 2, DoNothingByRef);
    1183                 :   }
    1184                 : 
    1185              221:   return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
    1186                 : }
    1187                 : 
    1188               10: RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
                        0: branch 1 not taken
                       10: branch 2 taken
    1189               10:   assert (ScratchArgs.isEmpty());
    1190                 :   return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
    1191               10:                               DoNothing, DoNothing);
    1192                 : }
    1193                 : 
    1194                 : //===----------------------------------------------------------------------===//
    1195                 : // Summary creation for Selectors.
    1196                 : //===----------------------------------------------------------------------===//
    1197                 : 
    1198                 : RetainSummary*
    1199               95: RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
                        0: branch 1 not taken
                       95: branch 2 taken
    1200               95:   assert(ScratchArgs.isEmpty());
    1201                 :   // 'init' methods conceptually return a newly allocated object and claim
    1202                 :   // the receiver.
                        0: branch 1 not taken
                       95: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                       95: branch 6 taken
                        0: branch 7 not taken
    1203               95:   if (cocoa::isCocoaObjectRef(RetTy) || cocoa::isCFObjectRef(RetTy))
    1204               95:     return getPersistentSummary(ObjCInitRetE, DecRefMsg);
    1205                 : 
    1206                0:   return getDefaultSummary();
    1207                 : }
    1208                 : 
    1209                 : void
    1210                 : RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
    1211             1240:                                                    const FunctionDecl *FD) {
                        0: branch 0 not taken
                     1240: branch 1 taken
    1212             1240:   if (!FD)
    1213                0:     return;
    1214                 : 
    1215             1240:   QualType RetTy = FD->getResultType();
    1216                 : 
    1217                 :   // Determine if there is a special return effect for this method.
                       36: branch 1 taken
                     1204: branch 2 taken
    1218             1240:   if (cocoa::isCocoaObjectRef(RetTy)) {
                        0: branch 1 not taken
                       36: branch 2 taken
    1219               36:     if (FD->getAttr<NSReturnsRetainedAttr>()) {
    1220                0:       Summ.setRetEffect(ObjCAllocRetE);
    1221                 :     }
                        0: branch 1 not taken
                       36: branch 2 taken
    1222               36:     else if (FD->getAttr<CFReturnsRetainedAttr>()) {
    1223                0:       Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
    1224                 :     }
    1225                 :   }
                      523: branch 2 taken
                      681: branch 3 taken
    1226             1204:   else if (RetTy->getAs<PointerType>()) {
                       24: branch 1 taken
                      499: branch 2 taken
    1227              523:     if (FD->getAttr<CFReturnsRetainedAttr>()) {
    1228               24:       Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
    1229                 :     }
    1230                 :   }
    1231                 : }
    1232                 : 
    1233                 : void
    1234                 : RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
    1235              364:                                                   const ObjCMethodDecl *MD) {
                        2: branch 0 taken
                      362: branch 1 taken
    1236              364:   if (!MD)
    1237                2:     return;
    1238                 : 
    1239              362:   bool isTrackedLoc = false;
    1240                 : 
    1241                 :   // Determine if there is a special return effect for this method.
                      243: branch 2 taken
                      119: branch 3 taken
    1242              362:   if (cocoa::isCocoaObjectRef(MD->getResultType())) {
                        8: branch 1 taken
                      235: branch 2 taken
    1243              243:     if (MD->getAttr<NSReturnsRetainedAttr>()) {
    1244                8:       Summ.setRetEffect(ObjCAllocRetE);
    1245                8:       return;
    1246                 :     }
    1247                 : 
    1248              235:     isTrackedLoc = true;
    1249                 :   }
    1250                 : 
                      119: branch 0 taken
                      235: branch 1 taken
    1251              354:   if (!isTrackedLoc)
    1252              119:     isTrackedLoc = MD->getResultType()->getAs<PointerType>() != NULL;
    1253                 : 
                      257: branch 0 taken
                       97: branch 1 taken
                       10: branch 3 taken
                      247: branch 4 taken
                       10: branch 5 taken
                      344: branch 6 taken
    1254              354:   if (isTrackedLoc && MD->getAttr<CFReturnsRetainedAttr>())
    1255               10:     Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
    1256                 : }
    1257                 : 
    1258                 : RetainSummary*
    1259                 : RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl* MD,
    1260              269:                                              Selector S, QualType RetTy) {
    1261                 : 
                      267: branch 0 taken
                        2: branch 1 taken
    1262              269:   if (MD) {
    1263                 :     // Scan the method decl for 'void*' arguments.  These should be treated
    1264                 :     // as 'StopTracking' because they are often used with delegates.
    1265                 :     // Delegates are a frequent form of false positives with the retain
    1266                 :     // count checker.
    1267              267:     unsigned i = 0;
                      185: branch 1 taken
                      267: branch 2 taken
    1268              719:     for (ObjCMethodDecl::param_iterator I = MD->param_begin(),
    1269              267:          E = MD->param_end(); I != E; ++I, ++i)
                      185: branch 0 taken
                        0: branch 1 not taken
    1270              185:       if (ParmVarDecl *PD = *I) {
    1271              185:         QualType Ty = Ctx.getCanonicalType(PD->getType());
                        0: branch 3 not taken
                      185: branch 4 taken
    1272              185:         if (Ty.getLocalUnqualifiedType() == Ctx.VoidPtrTy)
    1273                0:           ScratchArgs = AF.Add(ScratchArgs, i, StopTracking);
    1274                 :       }
    1275                 :   }
    1276                 : 
    1277                 :   // Any special effect for the receiver?
    1278              269:   ArgEffect ReceiverEff = DoNothing;
    1279                 : 
    1280                 :   // If one of the arguments in the selector has the keyword 'delegate' we
    1281                 :   // should stop tracking the reference count for the receiver.  This is
    1282                 :   // because the reference count is quite possibly handled by a delegate
    1283                 :   // method.
                      115: branch 1 taken
                      154: branch 2 taken
    1284              269:   if (S.isKeywordSelector()) {
    1285              115:     const std::string &str = S.getAsString();
                        0: branch 1 not taken
                      115: branch 2 taken
    1286              115:     assert(!str.empty());
                        2: branch 3 taken
                      113: branch 4 taken
    1287              115:     if (StrInStrNoCase(str, "delegate:") != StringRef::npos)
    1288                2:       ReceiverEff = StopTracking;
    1289                 :   }
    1290                 : 
    1291                 :   // Look for methods that return an owned object.
                      150: branch 1 taken
                      119: branch 2 taken
    1292              269:   if (cocoa::isCocoaObjectRef(RetTy)) {
    1293                 :     // EXPERIMENTAL: Assume the Cocoa conventions for all objects returned
    1294                 :     //  by instance methods.
    1295                 :     RetEffect E = cocoa::followsFundamentalRule(S)
                       26: branch 1 taken
                      124: branch 2 taken
    1296              150:                   ? ObjCAllocRetE : RetEffect::MakeNotOwned(RetEffect::ObjC);
    1297                 : 
    1298              150:     return getPersistentSummary(E, ReceiverEff, MayEscape);
    1299                 :   }
    1300                 : 
    1301                 :   // Look for methods that return an owned core foundation object.
                       18: branch 1 taken
                      101: branch 2 taken
    1302              119:   if (cocoa::isCFObjectRef(RetTy)) {
    1303                 :     RetEffect E = cocoa::followsFundamentalRule(S)
    1304                 :       ? RetEffect::MakeOwned(RetEffect::CF, true)
                       10: branch 1 taken
                        8: branch 2 taken
    1305               18:       : RetEffect::MakeNotOwned(RetEffect::CF);
    1306                 : 
    1307               18:     return getPersistentSummary(E, ReceiverEff, MayEscape);
    1308                 :   }
    1309                 : 
                      101: branch 1 taken
                        0: branch 2 not taken
                       99: branch 3 taken
                        2: branch 4 taken
                       99: branch 5 taken
                        2: branch 6 taken
    1310              101:   if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
    1311               99:     return getDefaultSummary();
    1312                 : 
    1313                2:   return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff, MayEscape);
    1314                 : }
    1315                 : 
    1316                 : RetainSummary*
    1317                 : RetainSummaryManager::getInstanceMethodSummary(const ObjCMessageExpr *ME,
    1318                 :                                                const GRState *state,
    1319              846:                                                const LocationContext *LC) {
    1320                 : 
    1321                 :   // We need the type-information of the tracked receiver object
    1322                 :   // Retrieve it from the state.
    1323              846:   const Expr *Receiver = ME->getReceiver();
    1324              846:   const ObjCInterfaceDecl* ID = 0;
    1325                 : 
    1326                 :   // FIXME: Is this really working as expected?  There are cases where
    1327                 :   //  we just use the 'ID' from the message expression.
    1328              846:   SVal receiverV = state->getSValAsScalarOrLoc(Receiver);
    1329                 :   
    1330                 :   // FIXME: Eventually replace the use of state->get<RefBindings> with
    1331                 :   // a generic API for reasoning about the Objective-C types of symbolic
    1332                 :   // objects.
                      809: branch 1 taken
                       37: branch 2 taken
    1333              846:   if (SymbolRef Sym = receiverV.getAsLocSymbol())
                      577: branch 1 taken
                      232: branch 2 taken
    1334              809:     if (const RefVal *T = state->get<RefBindings>(Sym))
                      214: branch 0 taken
                      363: branch 1 taken
    1335              577:       if (const ObjCObjectPointerType* PT = 
    1336              577:             T->getType()->getAs<ObjCObjectPointerType>())
    1337              214:         ID = PT->getInterfaceDecl();
    1338                 :   
    1339                 :   // FIXME: this is a hack.  This may or may not be the actual method
    1340                 :   //  that is called.
                      806: branch 0 taken
                       40: branch 1 taken
    1341              846:   if (!ID) {
                      804: branch 0 taken
                        2: branch 1 taken
    1342              806:     if (const ObjCObjectPointerType *PT =
    1343              806:         Receiver->getType()->getAs<ObjCObjectPointerType>())
    1344              804:       ID = PT->getInterfaceDecl();
    1345                 :   }
    1346                 :   
    1347                 :   // FIXME: The receiver could be a reference to a class, meaning that
    1348                 :   //  we should use the class method.
    1349              846:   RetainSummary *Summ = getInstanceMethodSummary(ME, ID);
    1350                 :   
    1351                 :   // Special-case: are we sending a mesage to "self"?
    1352                 :   //  This is a hack.  When we have full-IP this should be removed.
                      250: branch 2 taken
                      596: branch 3 taken
    1353              846:   if (isa<ObjCMethodDecl>(LC->getDecl())) {
                      214: branch 1 taken
                       36: branch 2 taken
    1354              250:     if (const loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&receiverV)) {
    1355                 :       // Get the region associated with 'self'.
                      214: branch 1 taken
                        0: branch 2 not taken
    1356              214:       if (const ImplicitParamDecl *SelfDecl = LC->getSelfDecl()) {
    1357              214:         SVal SelfVal = state->getSVal(state->getRegion(SelfDecl, LC));
                       26: branch 2 taken
                      188: branch 3 taken
    1358              214:         if (L->StripCasts() == SelfVal.getAsRegion()) {
    1359                 :           // Update the summary to make the default argument effect
    1360                 :           // 'StopTracking'.
    1361               26:           Summ = copySummary(Summ);
    1362               26:           Summ->setDefaultArgEffect(StopTracking);
    1363              214:         }
    1364                 :       }
    1365                 :     }
    1366                 :   }
    1367                 :   
                        0: branch 0 not taken
                      846: branch 1 taken
    1368              846:   return Summ ? Summ : getDefaultSummary();
    1369                 : }
    1370                 : 
    1371                 : RetainSummary*
    1372                 : RetainSummaryManager::getInstanceMethodSummary(Selector S,
    1373                 :                                                IdentifierInfo *ClsName,
    1374                 :                                                const ObjCInterfaceDecl* ID,
    1375                 :                                                const ObjCMethodDecl *MD,
    1376              900:                                                QualType RetTy) {
    1377                 : 
    1378                 :   // Look up a summary in our summary cache.
    1379              900:   RetainSummary *Summ = ObjCMethodSummaries.find(ID, ClsName, S);
    1380                 : 
                      286: branch 0 taken
                      614: branch 1 taken
    1381              900:   if (!Summ) {
                        0: branch 1 not taken
                      286: branch 2 taken
    1382              286:     assert(ScratchArgs.isEmpty());
    1383                 : 
    1384                 :     // "initXXX": pass-through for receiver.
                       95: branch 1 taken
                      191: branch 2 taken
    1385              286:     if (cocoa::deriveNamingConvention(S) == cocoa::InitRule)
    1386               95:       Summ = getInitMethodSummary(RetTy);
    1387                 :     else
    1388              191:       Summ = getCommonMethodSummary(MD, S, RetTy);
    1389                 : 
    1390                 :     // Annotations override defaults.
    1391              286:     updateSummaryFromAnnotations(*Summ, MD);
    1392                 : 
    1393                 :     // Memoize the summary.
    1394              286:     ObjCMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
    1395                 :   }
    1396                 : 
    1397              900:   return Summ;
    1398                 : }
    1399                 : 
    1400                 : RetainSummary*
    1401                 : RetainSummaryManager::getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
    1402                 :                                             const ObjCInterfaceDecl *ID,
    1403                 :                                             const ObjCMethodDecl *MD,
    1404              377:                                             QualType RetTy) {
    1405                 : 
                        0: branch 0 not taken
                      377: branch 1 taken
    1406              377:   assert(ClsName && "Class name must be specified.");
    1407              377:   RetainSummary *Summ = ObjCClassMethodSummaries.find(ID, ClsName, S);
    1408                 : 
                       78: branch 0 taken
                      299: branch 1 taken
    1409              377:   if (!Summ) {
    1410               78:     Summ = getCommonMethodSummary(MD, S, RetTy);
    1411                 :     // Annotations override defaults.
    1412               78:     updateSummaryFromAnnotations(*Summ, MD);
    1413                 :     // Memoize the summary.
    1414               78:     ObjCClassMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
    1415                 :   }
    1416                 : 
    1417              377:   return Summ;
    1418                 : }
    1419                 : 
    1420             2138: void RetainSummaryManager::InitializeClassMethodSummaries() {
                        0: branch 1 not taken
                     2138: branch 2 taken
    1421             2138:   assert(ScratchArgs.isEmpty());
    1422             2138:   RetainSummary* Summ = getPersistentSummary(ObjCAllocRetE);
    1423                 : 
    1424                 :   // Create the summaries for "alloc", "new", and "allocWithZone:" for
    1425                 :   // NSObject and its derivatives.
    1426             2138:   addNSObjectClsMethSummary(GetNullarySelector("alloc", Ctx), Summ);
    1427             2138:   addNSObjectClsMethSummary(GetNullarySelector("new", Ctx), Summ);
    1428             2138:   addNSObjectClsMethSummary(GetUnarySelector("allocWithZone", Ctx), Summ);
    1429                 : 
    1430                 :   // Create the [NSAssertionHandler currentHander] summary.
    1431                 :   addClassMethSummary("NSAssertionHandler", "currentHandler",
    1432             2138:                 getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC)));
    1433                 : 
    1434                 :   // Create the [NSAutoreleasePool addObject:] summary.
    1435             2138:   ScratchArgs = AF.Add(ScratchArgs, 0, Autorelease);
    1436                 :   addClassMethSummary("NSAutoreleasePool", "addObject",
    1437                 :                       getPersistentSummary(RetEffect::MakeNoRet(),
    1438             2138:                                            DoNothing, Autorelease));
    1439                 : 
    1440                 :   // Create a summary for [NSCursor dragCopyCursor].
    1441                 :   addClassMethSummary("NSCursor", "dragCopyCursor",
    1442                 :                       getPersistentSummary(RetEffect::MakeNoRet(), DoNothing,
    1443             2138:                                            DoNothing));
    1444                 : 
    1445                 :   // Create the summaries for [NSObject performSelector...].  We treat
    1446                 :   // these as 'stop tracking' for the arguments because they are often
    1447                 :   // used for delegates that can release the object.  When we have better
    1448                 :   // inter-procedural analysis we can potentially do something better.  This
    1449                 :   // workaround is to remove false positives.
    1450             2138:   Summ = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, StopTracking);
    1451             2138:   IdentifierInfo *NSObjectII = &Ctx.Idents.get("NSObject");
    1452                 :   addClsMethSummary(NSObjectII, Summ, "performSelector", "withObject",
    1453             2138:                     "afterDelay", NULL);
    1454                 :   addClsMethSummary(NSObjectII, Summ, "performSelector", "withObject",
    1455             2138:                     "afterDelay", "inModes", NULL);
    1456                 :   addClsMethSummary(NSObjectII, Summ, "performSelectorOnMainThread",
    1457             2138:                     "withObject", "waitUntilDone", NULL);
    1458                 :   addClsMethSummary(NSObjectII, Summ, "performSelectorOnMainThread",
    1459             2138:                     "withObject", "waitUntilDone", "modes", NULL);
    1460                 :   addClsMethSummary(NSObjectII, Summ, "performSelector", "onThread",
    1461             2138:                     "withObject", "waitUntilDone", NULL);
    1462                 :   addClsMethSummary(NSObjectII, Summ, "performSelector", "onThread",
    1463             2138:                     "withObject", "waitUntilDone", "modes", NULL);
    1464                 :   addClsMethSummary(NSObjectII, Summ, "performSelectorInBackground",
    1465             2138:                     "withObject", NULL);
    1466                 : 
    1467                 :   // Specially handle NSData.
    1468                 :   RetainSummary *dataWithBytesNoCopySumm =
    1469                 :     getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC), DoNothing,
    1470             2138:                          DoNothing);
    1471                 :   addClsMethSummary("NSData", dataWithBytesNoCopySumm,
    1472             2138:                     "dataWithBytesNoCopy", "length", NULL);
    1473                 :   addClsMethSummary("NSData", dataWithBytesNoCopySumm,
    1474             2138:                     "dataWithBytesNoCopy", "length", "freeWhenDone", NULL);
    1475             2138: }
    1476                 : 
    1477             2138: void RetainSummaryManager::InitializeMethodSummaries() {
    1478                 : 
                        0: branch 1 not taken
                     2138: branch 2 taken
    1479             2138:   assert (ScratchArgs.isEmpty());
    1480                 : 
    1481                 :   // Create the "init" selector.  It just acts as a pass-through for the
    1482                 :   // receiver.
    1483             2138:   RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE, DecRefMsg);
    1484             2138:   addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
    1485                 : 
    1486                 :   // awakeAfterUsingCoder: behaves basically like an 'init' method.  It
    1487                 :   // claims the receiver and returns a retained object.
    1488                 :   addNSObjectMethSummary(GetUnarySelector("awakeAfterUsingCoder", Ctx),
    1489             2138:                          InitSumm);
    1490                 : 
    1491                 :   // The next methods are allocators.
    1492             2138:   RetainSummary *AllocSumm = getPersistentSummary(ObjCAllocRetE);
    1493                 :   RetainSummary *CFAllocSumm =
    1494             2138:     getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
    1495                 : 
    1496                 :   // Create the "copy" selector.
    1497             2138:   addNSObjectMethSummary(GetNullarySelector("copy", Ctx), AllocSumm);
    1498                 : 
    1499                 :   // Create the "mutableCopy" selector.
    1500             2138:   addNSObjectMethSummary(GetNullarySelector("mutableCopy", Ctx), AllocSumm);
    1501                 : 
    1502                 :   // Create the "retain" selector.
    1503             2138:   RetEffect E = RetEffect::MakeReceiverAlias();
    1504             2138:   RetainSummary *Summ = getPersistentSummary(E, IncRefMsg);
    1505             2138:   addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
    1506                 : 
    1507                 :   // Create the "release" selector.
    1508             2138:   Summ = getPersistentSummary(E, DecRefMsg);
    1509             2138:   addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
    1510                 : 
    1511                 :   // Create the "drain" selector.
                      238: branch 1 taken
                     1900: branch 2 taken
    1512             2138:   Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : DecRef);
    1513             2138:   addNSObjectMethSummary(GetNullarySelector("drain", Ctx), Summ);
    1514                 : 
    1515                 :   // Create the -dealloc summary.
    1516             2138:   Summ = getPersistentSummary(RetEffect::MakeNoRet(), Dealloc);
    1517             2138:   addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ);
    1518                 : 
    1519                 :   // Create the "autorelease" selector.
    1520             2138:   Summ = getPersistentSummary(E, Autorelease);
    1521             2138:   addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
    1522                 : 
    1523                 :   // Specially handle NSAutoreleasePool.
    1524                 :   addInstMethSummary("NSAutoreleasePool", "init",
    1525                 :                      getPersistentSummary(RetEffect::MakeReceiverAlias(),
    1526             2138:                                           NewAutoreleasePool));
    1527                 : 
    1528                 :   // For NSWindow, allocated objects are (initially) self-owned.
    1529                 :   // FIXME: For now we opt for false negatives with NSWindow, as these objects
    1530                 :   //  self-own themselves.  However, they only do this once they are displayed.
    1531                 :   //  Thus, we need to track an NSWindow's display status.
    1532                 :   //  This is tracked in <rdar://problem/6062711>.
    1533                 :   //  See also http://llvm.org/bugs/show_bug.cgi?id=3714.
    1534                 :   RetainSummary *NoTrackYet = getPersistentSummary(RetEffect::MakeNoRet(),
    1535                 :                                                    StopTracking,
    1536             2138:                                                    StopTracking);
    1537                 : 
    1538             2138:   addClassMethSummary("NSWindow", "alloc", NoTrackYet);
    1539                 : 
    1540                 : #if 0
    1541                 :   addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect",
    1542                 :                      "styleMask", "backing", "defer", NULL);
    1543                 : 
    1544                 :   addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect",
    1545                 :                      "styleMask", "backing", "defer", "screen", NULL);
    1546                 : #endif
    1547                 : 
    1548                 :   // For NSPanel (which subclasses NSWindow), allocated objects are not
    1549                 :   //  self-owned.
    1550                 :   // FIXME: For now we don't track NSPanels. object for the same reason
    1551                 :   //   as for NSWindow objects.
    1552             2138:   addClassMethSummary("NSPanel", "alloc", NoTrackYet);
    1553                 : 
    1554                 : #if 0
    1555                 :   addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect",
    1556                 :                      "styleMask", "backing", "defer", NULL);
    1557                 : 
    1558                 :   addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect",
    1559                 :                      "styleMask", "backing", "defer", "screen", NULL);
    1560                 : #endif
    1561                 : 
    1562                 :   // Don't track allocated autorelease pools yet, as it is okay to prematurely
    1563                 :   // exit a method.
    1564             2138:   addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet);
    1565                 : 
    1566                 :   // Create NSAssertionHandler summaries.
    1567                 :   addPanicSummary("NSAssertionHandler", "handleFailureInFunction", "file",
    1568             2138:                   "lineNumber", "description", NULL);
    1569                 : 
    1570                 :   addPanicSummary("NSAssertionHandler", "handleFailureInMethod", "object",
    1571             2138:                   "file", "lineNumber", "description", NULL);
    1572                 : 
    1573                 :   // Create summaries QCRenderer/QCView -createSnapShotImageOfType:
    1574                 :   addInstMethSummary("QCRenderer", AllocSumm,
    1575             2138:                      "createSnapshotImageOfType", NULL);
    1576                 :   addInstMethSummary("QCView", AllocSumm,
    1577             2138:                      "createSnapshotImageOfType", NULL);
    1578                 : 
    1579                 :   // Create summaries for CIContext, 'createCGImage' and
    1580                 :   // 'createCGLayerWithSize'.  These objects are CF objects, and are not
    1581                 :   // automatically garbage collected.
    1582                 :   addInstMethSummary("CIContext", CFAllocSumm,
    1583             2138:                      "createCGImage", "fromRect", NULL);
    1584                 :   addInstMethSummary("CIContext", CFAllocSumm,
    1585             2138:                      "createCGImage", "fromRect", "format", "colorSpace", NULL);
    1586                 :   addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize",
    1587             2138:            "info", NULL);
    1588             2138: }
    1589                 : 
    1590                 : //===----------------------------------------------------------------------===//
    1591                 : // AutoreleaseBindings - State used to track objects in autorelease pools.
    1592                 : //===----------------------------------------------------------------------===//
    1593                 : 
    1594                 : typedef llvm::ImmutableMap<SymbolRef, unsigned> ARCounts;
    1595                 : typedef llvm::ImmutableMap<SymbolRef, ARCounts> ARPoolContents;
    1596                 : typedef llvm::ImmutableList<SymbolRef> ARStack;
    1597                 : 
    1598                 : static int AutoRCIndex = 0;
    1599                 : static int AutoRBIndex = 0;
    1600                 : 
    1601                 : namespace { class AutoreleasePoolContents {}; }
    1602                 : namespace { class AutoreleaseStack {}; }
    1603                 : 
    1604                 : namespace clang {
    1605                 : template<> struct GRStateTrait<AutoreleaseStack>
    1606                 :   : public GRStatePartialTrait<ARStack> {
    1607               66:   static inline void* GDMIndex() { return &AutoRBIndex; }
    1608                 : };
    1609                 : 
    1610                 : template<> struct GRStateTrait<AutoreleasePoolContents>
    1611                 :   : public GRStatePartialTrait<ARPoolContents> {
    1612              264:   static inline void* GDMIndex() { return &AutoRCIndex; }
    1613                 : };
    1614                 : } // end clang namespace
    1615                 : 
    1616               66: static SymbolRef GetCurrentAutoreleasePool(const GRState* state) {
    1617               66:   ARStack stack = state->get<AutoreleaseStack>();
                       66: branch 1 taken
                        0: branch 2 not taken
    1618               66:   return stack.isEmpty() ? SymbolRef() : stack.getHead();
    1619                 : }
    1620                 : 
    1621                 : static const GRState * SendAutorelease(const GRState *state,
    1622               66:                                        ARCounts::Factory &F, SymbolRef sym) {
    1623                 : 
    1624               66:   SymbolRef pool = GetCurrentAutoreleasePool(state);
    1625               66:   const ARCounts *cnts = state->get<AutoreleasePoolContents>(pool);
    1626               66:   ARCounts newCnts(0);
    1627                 : 
                       22: branch 0 taken
                       44: branch 1 taken
    1628               66:   if (cnts) {
    1629               22:     const unsigned *cnt = (*cnts).lookup(sym);
                       10: branch 0 taken
                       12: branch 1 taken
    1630               22:     newCnts = F.Add(*cnts, sym, cnt ? *cnt  + 1 : 1);
    1631                 :   }
    1632                 :   else
    1633               44:     newCnts = F.Add(F.GetEmptyMap(), sym, 1);
    1634                 : 
    1635               66:   return state->set<AutoreleasePoolContents>(pool, newCnts);
    1636                 : }
    1637                 : 
    1638                 : //===----------------------------------------------------------------------===//
    1639                 : // Transfer functions.
    1640                 : //===----------------------------------------------------------------------===//
    1641                 : 
    1642                 : namespace {
    1643                 : 
    1644                 : class CFRefCount : public GRTransferFuncs {
    1645                 : public:
                     2138: branch 2 taken
                        0: branch 3 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
    1646             4276:   class BindingsPrinter : public GRState::Printer {
    1647                 :   public:
    1648                 :     virtual void Print(llvm::raw_ostream& Out, const GRState* state,
    1649                 :                        const char* nl, const char* sep);
    1650                 :   };
    1651                 : 
    1652                 : private:
    1653                 :   typedef llvm::DenseMap<const ExplodedNode*, const RetainSummary*>
    1654                 :     SummaryLogTy;
    1655                 : 
    1656                 :   RetainSummaryManager Summaries;
    1657                 :   SummaryLogTy SummaryLog;
    1658                 :   const LangOptions&   LOpts;
    1659                 :   ARCounts::Factory    ARCountFactory;
    1660                 : 
    1661                 :   BugType *useAfterRelease, *releaseNotOwned;
    1662                 :   BugType *deallocGC, *deallocNotOwned;
    1663                 :   BugType *leakWithinFunction, *leakAtReturn;
    1664                 :   BugType *overAutorelease;
    1665                 :   BugType *returnNotOwnedForOwned;
    1666                 :   BugReporter *BR;
    1667                 : 
    1668                 :   const GRState * Update(const GRState * state, SymbolRef sym, RefVal V, ArgEffect E,
    1669                 :                     RefVal::Kind& hasErr);
    1670                 : 
    1671                 :   void ProcessNonLeakError(ExplodedNodeSet& Dst,
    1672                 :                            GRStmtNodeBuilder& Builder,
    1673                 :                            Expr* NodeExpr, Expr* ErrorExpr,
    1674                 :                            ExplodedNode* Pred,
    1675                 :                            const GRState* St,
    1676                 :                            RefVal::Kind hasErr, SymbolRef Sym);
    1677                 : 
    1678                 :   const GRState * HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
    1679                 :                                llvm::SmallVectorImpl<SymbolRef> &Leaked);
    1680                 : 
    1681                 :   ExplodedNode* ProcessLeaks(const GRState * state,
    1682                 :                                       llvm::SmallVectorImpl<SymbolRef> &Leaked,
    1683                 :                                       GenericNodeBuilder &Builder,
    1684                 :                                       GRExprEngine &Eng,
    1685                 :                                       ExplodedNode *Pred = 0);
    1686                 : 
    1687                 : public:
    1688             2138:   CFRefCount(ASTContext& Ctx, bool gcenabled, const LangOptions& lopts)
    1689                 :     : Summaries(Ctx, gcenabled),
    1690                 :       LOpts(lopts), useAfterRelease(0), releaseNotOwned(0),
    1691                 :       deallocGC(0), deallocNotOwned(0),
    1692                 :       leakWithinFunction(0), leakAtReturn(0), overAutorelease(0),
    1693             2138:       returnNotOwnedForOwned(0), BR(0) {}
    1694                 : 
                     2138: branch 4 taken
                        0: branch 5 not taken
                        0: branch 11 not taken
                        0: branch 12 not taken
    1695             2138:   virtual ~CFRefCount() {}
    1696                 : 
    1697                 :   void RegisterChecks(GRExprEngine &Eng);
    1698                 : 
    1699             2138:   virtual void RegisterPrinters(std::vector<GRState::Printer*>& Printers) {
    1700             2138:     Printers.push_back(new BindingsPrinter());
    1701             2138:   }
    1702                 : 
    1703             8572:   bool isGCEnabled() const { return Summaries.isGCEnabled(); }
    1704             7453:   const LangOptions& getLangOptions() const { return LOpts; }
    1705                 : 
    1706             1713:   const RetainSummary *getSummaryOfNode(const ExplodedNode *N) const {
    1707             1713:     SummaryLogTy::const_iterator I = SummaryLog.find(N);
                     1419: branch 2 taken
                      294: branch 3 taken
    1708             1713:     return I == SummaryLog.end() ? 0 : I->second;
    1709                 :   }
    1710                 : 
    1711                 :   // Calls.
    1712                 : 
    1713                 :   void EvalSummary(ExplodedNodeSet& Dst,
    1714                 :                    GRExprEngine& Eng,
    1715                 :                    GRStmtNodeBuilder& Builder,
    1716                 :                    Expr* Ex,
    1717                 :                    Expr* Receiver,
    1718                 :                    const RetainSummary& Summ,
    1719                 :                    const MemRegion *Callee,
    1720                 :                    ExprIterator arg_beg, ExprIterator arg_end,
    1721                 :                    ExplodedNode* Pred, const GRState *state);
    1722                 : 
    1723                 :   virtual void EvalCall(ExplodedNodeSet& Dst,
    1724                 :                         GRExprEngine& Eng,
    1725                 :                         GRStmtNodeBuilder& Builder,
    1726                 :                         CallExpr* CE, SVal L,
    1727                 :                         ExplodedNode* Pred);
    1728                 : 
    1729                 : 
    1730                 :   virtual void EvalObjCMessageExpr(ExplodedNodeSet& Dst,
    1731                 :                                    GRExprEngine& Engine,
    1732                 :                                    GRStmtNodeBuilder& Builder,
    1733                 :                                    ObjCMessageExpr* ME,
    1734                 :                                    ExplodedNode* Pred,
    1735                 :                                    const GRState *state);
    1736                 : 
    1737                 :   bool EvalObjCMessageExprAux(ExplodedNodeSet& Dst,
    1738                 :                               GRExprEngine& Engine,
    1739                 :                               GRStmtNodeBuilder& Builder,
    1740                 :                               ObjCMessageExpr* ME,
    1741                 :                               ExplodedNode* Pred);
    1742                 : 
    1743                 :   // Stores.
    1744                 :   virtual void EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val);
    1745                 : 
    1746                 :   // End-of-path.
    1747                 : 
    1748                 :   virtual void EvalEndPath(GRExprEngine& Engine,
    1749                 :                            GREndPathNodeBuilder& Builder);
    1750                 : 
    1751                 :   virtual void EvalDeadSymbols(ExplodedNodeSet& Dst,
    1752                 :                                GRExprEngine& Engine,
    1753                 :                                GRStmtNodeBuilder& Builder,
    1754                 :                                ExplodedNode* Pred,
    1755                 :                                Stmt* S, const GRState* state,
    1756                 :                                SymbolReaper& SymReaper);
    1757                 : 
    1758                 :   std::pair<ExplodedNode*, const GRState *>
    1759                 :   HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd,
    1760                 :                           ExplodedNode* Pred, GRExprEngine &Eng,
    1761                 :                           SymbolRef Sym, RefVal V, bool &stop);
    1762                 :   // Return statements.
    1763                 : 
    1764                 :   virtual void EvalReturn(ExplodedNodeSet& Dst,
    1765                 :                           GRExprEngine& Engine,
    1766                 :                           GRStmtNodeBuilder& Builder,
    1767                 :                           ReturnStmt* S,
    1768                 :                           ExplodedNode* Pred);
    1769                 : 
    1770                 :   // Assumptions.
    1771                 : 
    1772                 :   virtual const GRState *EvalAssume(const GRState* state, SVal condition,
    1773                 :                                     bool assumption);
    1774                 : };
    1775                 : 
    1776                 : } // end anonymous namespace
    1777                 : 
    1778                 : static void PrintPool(llvm::raw_ostream &Out, SymbolRef Sym,
    1779                0:                       const GRState *state) {
    1780                0:   Out << ' ';
                        0: branch 0 not taken
                        0: branch 1 not taken
    1781                0:   if (Sym)
    1782                0:     Out << Sym->getSymbolID();
    1783                 :   else
    1784                0:     Out << "<pool>";
    1785                0:   Out << ":{";
    1786                 : 
    1787                 :   // Get the contents of the pool.
                        0: branch 1 not taken
                        0: branch 2 not taken
    1788                0:   if (const ARCounts *cnts = state->get<AutoreleasePoolContents>(Sym))
                        0: branch 4 not taken
                        0: branch 5 not taken
    1789                0:     for (ARCounts::iterator J=cnts->begin(), EJ=cnts->end(); J != EJ; ++J)
    1790                0:       Out << '(' << J.getKey() << ',' << J.getData() << ')';
    1791                 : 
    1792                0:   Out << '}';
    1793                0: }
    1794                 : 
    1795                 : void CFRefCount::BindingsPrinter::Print(llvm::raw_ostream& Out,
    1796                 :                                         const GRState* state,
    1797                0:                                         const char* nl, const char* sep) {
    1798                 : 
    1799                0:   RefBindings B = state->get<RefBindings>();
    1800                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
    1801                0:   if (!B.isEmpty())
    1802                0:     Out << sep << nl;
    1803                 : 
                        0: branch 4 not taken
                        0: branch 5 not taken
    1804                0:   for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
    1805                0:     Out << (*I).first << " : ";
    1806                0:     (*I).second.print(Out);
    1807                0:     Out << nl;
    1808                0:   }
    1809                 : 
    1810                 :   // Print the autorelease stack.
    1811                0:   Out << sep << nl << "AR pool stack:";
    1812                0:   ARStack stack = state->get<AutoreleaseStack>();
    1813                 : 
    1814                0:   PrintPool(Out, SymbolRef(), state);  // Print the caller's pool.
                        0: branch 4 not taken
                        0: branch 5 not taken
    1815                0:   for (ARStack::iterator I=stack.begin(), E=stack.end(); I!=E; ++I)
    1816                0:     PrintPool(Out, *I, state);
    1817                 : 
    1818                0:   Out << nl;
    1819                0: }
    1820                 : 
    1821                 : //===----------------------------------------------------------------------===//
    1822                 : // Error reporting.
    1823                 : //===----------------------------------------------------------------------===//
    1824                 : 
    1825                 : namespace {
    1826                 : 
    1827                 :   //===-------------===//
    1828                 :   // Bug Descriptions. //
    1829                 :   //===-------------===//
    1830                 : 
                        0: branch 1 not taken
                    17104: branch 2 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 9 not taken
                        0: branch 10 not taken
    1831            17104:   class CFRefBug : public BugType {
    1832                 :   protected:
    1833                 :     CFRefCount& TF;
    1834                 : 
    1835            17104:     CFRefBug(CFRefCount* tf, llvm::StringRef name)
    1836            17104:     : BugType(name, "Memory (Core Foundation/Objective-C)"), TF(*tf) {}
    1837                 :   public:
    1838                 : 
    1839              454:     CFRefCount& getTF() { return TF; }
    1840                 :     const CFRefCount& getTF() const { return TF; }
    1841                 : 
    1842                 :     // FIXME: Eventually remove.
    1843                 :     virtual const char* getDescription() const = 0;
    1844                 : 
    1845              110:     virtual bool isLeak() const { return false; }
    1846                 :   };
    1847                 : 
                     2138: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    1848             2138:   class UseAfterRelease : public CFRefBug {
    1849                 :   public:
    1850             2138:     UseAfterRelease(CFRefCount* tf)
    1851             2138:     : CFRefBug(tf, "Use-after-release") {}
    1852                 : 
    1853               35:     const char* getDescription() const {
    1854               35:       return "Reference-counted object is used after it is released";
    1855                 :     }
    1856                 :   };
    1857                 : 
                     2138: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    1858             2138:   class BadRelease : public CFRefBug {
    1859                 :   public:
    1860             2138:     BadRelease(CFRefCount* tf) : CFRefBug(tf, "Bad release") {}
    1861                 : 
    1862               10:     const char* getDescription() const {
    1863                 :       return "Incorrect decrement of the reference count of an object that is "
    1864               10:              "not owned at this point by the caller";
    1865                 :     }
    1866                 :   };
    1867                 : 
                     2138: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    1868             2138:   class DeallocGC : public CFRefBug {
    1869                 :   public:
    1870             2138:     DeallocGC(CFRefCount *tf)
    1871             2138:       : CFRefBug(tf, "-dealloc called while using garbage collection") {}
    1872                 : 
    1873                0:     const char *getDescription() const {
    1874                0:       return "-dealloc called while using garbage collection";
    1875                 :     }
    1876                 :   };
    1877                 : 
                     2138: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    1878             2138:   class DeallocNotOwned : public CFRefBug {
    1879                 :   public:
    1880             2138:     DeallocNotOwned(CFRefCount *tf)
    1881             2138:       : CFRefBug(tf, "-dealloc sent to non-exclusively owned object") {}
    1882                 : 
    1883                0:     const char *getDescription() const {
    1884                0:       return "-dealloc sent to object that may be referenced elsewhere";
    1885                 :     }
    1886                 :   };
    1887                 : 
                     2138: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    1888             2138:   class OverAutorelease : public CFRefBug {
    1889                 :   public:
    1890             2138:     OverAutorelease(CFRefCount *tf) :
    1891             2138:       CFRefBug(tf, "Object sent -autorelease too many times") {}
    1892                 : 
    1893                6:     const char *getDescription() const {
    1894                6:       return "Object sent -autorelease too many times";
    1895                 :     }
    1896                 :   };
    1897                 : 
                     2138: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    1898             2138:   class ReturnedNotOwnedForOwned : public CFRefBug {
    1899                 :   public:
    1900             2138:     ReturnedNotOwnedForOwned(CFRefCount *tf) :
    1901             2138:       CFRefBug(tf, "Method should return an owned object") {}
    1902                 : 
    1903                4:     const char *getDescription() const {
    1904                 :       return "Object with +0 retain counts returned to caller where a +1 "
    1905                4:              "(owning) retain count is expected";
    1906                 :     }
    1907                 :   };
    1908                 : 
                        0: branch 1 not taken
                     4276: branch 2 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 9 not taken
                        0: branch 10 not taken
    1909             4276:   class Leak : public CFRefBug {
    1910                 :     const bool isReturn;
    1911                 :   protected:
    1912             4276:     Leak(CFRefCount* tf, llvm::StringRef name, bool isRet)
    1913             4276:     : CFRefBug(tf, name), isReturn(isRet) {}
    1914                 :   public:
    1915                 : 
    1916              190:     const char* getDescription() const { return ""; }
    1917                 : 
    1918              182:     bool isLeak() const { return true; }
    1919                 :   };
    1920                 : 
                     2138: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    1921             2138:   class LeakAtReturn : public Leak {
    1922                 :   public:
    1923             2138:     LeakAtReturn(CFRefCount* tf, llvm::StringRef name)
    1924             2138:     : Leak(tf, name, true) {}
    1925                 :   };
    1926                 : 
                     2138: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    1927             2138:   class LeakWithinFunction : public Leak {
    1928                 :   public:
    1929             2138:     LeakWithinFunction(CFRefCount* tf, llvm::StringRef name)
    1930             2138:     : Leak(tf, name, false) {}
    1931                 :   };
    1932                 : 
    1933                 :   //===---------===//
    1934                 :   // Bug Reports.  //
    1935                 :   //===---------===//
    1936                 : 
    1937                 :   class CFRefReport : public RangedBugReport {
    1938                 :   protected:
    1939                 :     SymbolRef Sym;
    1940                 :     const CFRefCount &TF;
    1941                 :   public:
    1942                 :     CFRefReport(CFRefBug& D, const CFRefCount &tf,
    1943              239:                 ExplodedNode *n, SymbolRef sym)
    1944              239:       : RangedBugReport(D, D.getDescription(), n), Sym(sym), TF(tf) {}
    1945                 : 
    1946                 :     CFRefReport(CFRefBug& D, const CFRefCount &tf,
    1947                6:                 ExplodedNode *n, SymbolRef sym, llvm::StringRef endText)
    1948                6:       : RangedBugReport(D, D.getDescription(), endText, n), Sym(sym), TF(tf) {}
    1949                 : 
                       55: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 9 not taken
                      190: branch 10 taken
    1950              245:     virtual ~CFRefReport() {}
    1951                 : 
    1952              746:     CFRefBug& getBugType() {
    1953              746:       return (CFRefBug&) RangedBugReport::getBugType();
    1954                 :     }
    1955                 :     const CFRefBug& getBugType() const {
    1956                 :       return (const CFRefBug&) RangedBugReport::getBugType();
    1957                 :     }
    1958                 : 
    1959              292:     virtual void getRanges(const SourceRange*& beg, const SourceRange*& end) {
                      110: branch 2 taken
                      182: branch 3 taken
    1960              292:       if (!getBugType().isLeak())
    1961              110:         RangedBugReport::getRanges(beg, end);
    1962                 :       else
    1963              182:         beg = end = 0;
    1964              292:     }
    1965                 : 
    1966              190:     SymbolRef getSymbol() const { return Sym; }
    1967                 : 
    1968                 :     PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
    1969                 :                                     const ExplodedNode* N);
    1970                 : 
    1971                 :     std::pair<const char**,const char**> getExtraDescriptiveText();
    1972                 : 
    1973                 :     PathDiagnosticPiece* VisitNode(const ExplodedNode* N,
    1974                 :                                    const ExplodedNode* PrevN,
    1975                 :                                    BugReporterContext& BRC);
    1976                 :   };
    1977                 : 
                      190: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
    1978              190:   class CFRefLeakReport : public CFRefReport {
    1979                 :     SourceLocation AllocSite;
    1980                 :     const MemRegion* AllocBinding;
    1981                 :   public:
    1982                 :     CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
    1983                 :                     ExplodedNode *n, SymbolRef sym,
    1984                 :                     GRExprEngine& Eng);
    1985                 : 
    1986                 :     PathDiagnosticPiece* getEndPath(BugReporterContext& BRC,
    1987                 :                                     const ExplodedNode* N);
    1988                 : 
    1989              559:     SourceLocation getLocation() const { return AllocSite; }
    1990                 :   };
    1991                 : } // end anonymous namespace
    1992                 : 
    1993                 : 
    1994                 : 
    1995                 : static const char* Msgs[] = {
    1996                 :   // GC only
    1997                 :   "Code is compiled to only use garbage collection",
    1998                 :   // No GC.
    1999                 :   "Code is compiled to use reference counts",
    2000                 :   // Hybrid, with GC.
    2001                 :   "Code is compiled to use either garbage collection (GC) or reference counts"
    2002                 :   " (non-GC).  The bug occurs with GC enabled",
    2003                 :   // Hybrid, without GC
    2004                 :   "Code is compiled to use either garbage collection (GC) or reference counts"
    2005                 :   " (non-GC).  The bug occurs in non-GC mode"
    2006                 : };
    2007                 : 
    2008              237: std::pair<const char**,const char**> CFRefReport::getExtraDescriptiveText() {
    2009              237:   CFRefCount& TF = static_cast<CFRefBug&>(getBugType()).getTF();
    2010                 : 
                        0: branch 2 not taken
                       20: branch 3 taken
                      189: branch 4 taken
                       28: branch 5 taken
    2011              237:   switch (TF.getLangOptions().getGCMode()) {
    2012                 :     default:
    2013                0:       assert(false);
    2014                 : 
    2015                 :     case LangOptions::GCOnly:
                        0: branch 1 not taken
                       20: branch 2 taken
    2016               20:       assert (TF.isGCEnabled());
    2017               20:       return std::make_pair(&Msgs[0], &Msgs[0]+1);
    2018                 : 
    2019                 :     case LangOptions::NonGC:
                        0: branch 1 not taken
                      189: branch 2 taken
    2020              189:       assert (!TF.isGCEnabled());
    2021              189:       return std::make_pair(&Msgs[1], &Msgs[1]+1);
    2022                 : 
    2023                 :     case LangOptions::HybridGC:
                        9: branch 1 taken
                       19: branch 2 taken
    2024               28:       if (TF.isGCEnabled())
    2025                9:         return std::make_pair(&Msgs[2], &Msgs[2]+1);
    2026                 :       else
    2027               19:         return std::make_pair(&Msgs[3], &Msgs[3]+1);
    2028                 :   }
    2029                 : }
    2030                 : 
    2031                 : static inline bool contains(const llvm::SmallVectorImpl<ArgEffect>& V,
    2032             3283:                             ArgEffect X) {
                      390: branch 2 taken
                     3267: branch 3 taken
    2033             3657:   for (llvm::SmallVectorImpl<ArgEffect>::const_iterator I=V.begin(), E=V.end();
    2034                 :        I!=E; ++I)
                       16: branch 0 taken
                      374: branch 1 taken
    2035              390:     if (*I == X) return true;
    2036                 : 
    2037             3267:   return false;
    2038                 : }
    2039                 : 
    2040                 : PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
    2041                 :                                             const ExplodedNode* PrevN,
    2042             4380:                                             BugReporterContext& BRC) {
    2043                 : 
                      514: branch 2 taken
                     3866: branch 3 taken
    2044             4380:   if (!isa<PostStmt>(N->getLocation()))
    2045              514:     return NULL;
    2046                 : 
    2047                 :   // Check if the type state has changed.
    2048             3866:   const GRState *PrevSt = PrevN->getState();
    2049             3866:   const GRState *CurrSt = N->getState();
    2050                 : 
    2051             3866:   const RefVal* CurrT = CurrSt->get<RefBindings>(Sym);
                     1916: branch 0 taken
                     1950: branch 1 taken
    2052             3866:   if (!CurrT) return NULL;
    2053                 : 
    2054             1950:   const RefVal &CurrV = *CurrT;
    2055             1950:   const RefVal *PrevT = PrevSt->get<RefBindings>(Sym);
    2056                 : 
    2057                 :   // Create a string buffer to constain all the useful things we want
    2058                 :   // to tell the user.
    2059             1950:   std::string sbuf;
    2060             1950:   llvm::raw_string_ostream os(sbuf);
    2061                 : 
    2062                 :   // This is the allocation site since the previous node had no bindings
    2063                 :   // for this symbol.
                      237: branch 0 taken
                     1713: branch 1 taken
    2064             1950:   if (!PrevT) {
    2065              237:     const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
    2066                 : 
                      129: branch 1 taken
                      108: branch 2 taken
    2067              237:     if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
    2068                 :       // Get the name of the callee (if it is available).
    2069              129:       SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee());
                      129: branch 1 taken
                        0: branch 2 not taken
    2070              129:       if (const FunctionDecl* FD = X.getAsFunctionDecl())
    2071              129:         os << "Call to function '" << FD->getNameAsString() <<'\'';
    2072                 :       else
    2073                0:         os << "function call";
    2074                 :     }
    2075                 :     else {
                        0: branch 1 not taken
                      108: branch 2 taken
    2076              108:       assert (isa<ObjCMessageExpr>(S));
    2077              108:       os << "Method";
    2078                 :     }
    2079                 : 
                      143: branch 1 taken
                       94: branch 2 taken
    2080              237:     if (CurrV.getObjKind() == RetEffect::CF) {
    2081              143:       os << " returns a Core Foundation object with a ";
    2082                 :     }
    2083                 :     else {
                        0: branch 1 not taken
                       94: branch 2 taken
    2084               94:       assert (CurrV.getObjKind() == RetEffect::ObjC);
    2085               94:       os << " returns an Objective-C object with a ";
    2086                 :     }
    2087                 : 
                      217: branch 1 taken
                       20: branch 2 taken
    2088              237:     if (CurrV.isOwned()) {
    2089              217:       os << "+1 retain count (owning reference).";
    2090                 : 
                       27: branch 3 taken
                      190: branch 4 taken
    2091              217:       if (static_cast<CFRefBug&>(getBugType()).getTF().isGCEnabled()) {
                        0: branch 1 not taken
                       27: branch 2 taken
    2092               27:         assert(CurrV.getObjKind() == RetEffect::CF);
    2093                 :         os << "  "
    2094               27:         "Core Foundation objects are not automatically garbage collected.";
    2095                 :       }
    2096                 :     }
    2097                 :     else {
                        0: branch 1 not taken
                       20: branch 2 taken
    2098               20:       assert (CurrV.isNotOwned());
    2099               20:       os << "+0 retain count (non-owning reference).";
    2100                 :     }
    2101                 : 
    2102              237:     PathDiagnosticLocation Pos(S, BRC.getSourceManager());
    2103              237:     return new PathDiagnosticEventPiece(Pos, os.str());
    2104                 :   }
    2105                 : 
    2106                 :   // Gather up the effects that were performed on the object at this
    2107                 :   // program point
    2108             1713:   llvm::SmallVector<ArgEffect, 2> AEffects;
    2109                 : 
                      294: branch 0 taken
                     1419: branch 1 taken
    2110             1713:   if (const RetainSummary *Summ =
    2111             1713:         TF.getSummaryOfNode(BRC.getNodeResolver().getOriginalNode(N))) {
    2112                 :     // We only have summaries attached to nodes after evaluating CallExpr and
    2113                 :     // ObjCMessageExprs.
    2114              294:     const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
    2115                 : 
                      114: branch 1 taken
                      180: branch 2 taken
    2116              294:     if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
    2117                 :       // Iterate through the parameter expressions and see if the symbol
    2118                 :       // was ever passed as an argument.
    2119              114:       unsigned i = 0;
    2120                 : 
                      176: branch 4 taken
                      114: branch 5 taken
    2121              290:       for (CallExpr::const_arg_iterator AI=CE->arg_begin(), AE=CE->arg_end();
    2122                 :            AI!=AE; ++AI, ++i) {
    2123                 : 
    2124                 :         // Retrieve the value of the argument.  Is it the symbol
    2125                 :         // we are interested in?
                       76: branch 4 taken
                      100: branch 5 taken
    2126              176:         if (CurrSt->getSValAsScalarOrLoc(*AI).getAsLocSymbol() != Sym)
    2127               76:           continue;
    2128                 : 
    2129                 :         // We have an argument.  Get the effect!
    2130              100:         AEffects.push_back(Summ->getArg(i));
    2131                 :       }
    2132                 :     }
                      180: branch 1 taken
                        0: branch 2 not taken
    2133              180:     else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {
                      160: branch 1 taken
                       20: branch 2 taken
    2134              180:       if (const Expr *receiver = ME->getReceiver())
                      110: branch 3 taken
                       50: branch 4 taken
    2135              160:         if (CurrSt->getSValAsScalarOrLoc(receiver).getAsLocSymbol() == Sym) {
    2136                 :           // The symbol we are tracking is the receiver.
    2137              110:           AEffects.push_back(Summ->getReceiverEffect());
    2138                 :         }
    2139                 :     }
    2140                 :   }
    2141                 : 
    2142                 :   do {
    2143                 :     // Get the previous type state.
    2144             1713:     RefVal PrevV = *PrevT;
    2145                 : 
    2146                 :     // Specially handle -dealloc.
                     1572: branch 1 taken
                      141: branch 2 taken
                        2: branch 4 taken
                     1570: branch 5 taken
                        2: branch 6 taken
                     1711: branch 7 taken
    2147             1713:     if (!TF.isGCEnabled() && contains(AEffects, Dealloc)) {
    2148                 :       // Determine if the object's reference count was pushed to zero.
                        2: branch 1 taken
                        0: branch 2 not taken
    2149                2:       assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
    2150                 :       // We may not have transitioned to 'release' if we hit an error.
    2151                 :       // This case is handled elsewhere.
                        2: branch 1 taken
                        0: branch 2 not taken
    2152                2:       if (CurrV.getKind() == RefVal::Released) {
                        0: branch 1 not taken
                        2: branch 2 taken
    2153                2:         assert(CurrV.getCombinedCounts() == 0);
    2154                2:         os << "Object released by directly sending the '-dealloc' message";
    2155                2:         break;
    2156                 :       }
    2157                 :     }
    2158                 : 
    2159                 :     // Specially handle CFMakeCollectable and friends.
                       14: branch 1 taken
                     1697: branch 2 taken
    2160             1711:     if (contains(AEffects, MakeCollectable)) {
    2161                 :       // Get the name of the function.
    2162               14:       const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
    2163               14:       SVal X = CurrSt->getSValAsScalarOrLoc(cast<CallExpr>(S)->getCallee());
    2164               14:       const FunctionDecl* FD = X.getAsFunctionDecl();
    2165               14:       const std::string& FName = FD->getNameAsString();
    2166                 : 
                        4: branch 1 taken
                       10: branch 2 taken
    2167               14:       if (TF.isGCEnabled()) {
    2168                 :         // Determine if the object's reference count was pushed to zero.
                        4: branch 1 taken
                        0: branch 2 not taken
    2169                4:         assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
    2170                 : 
    2171                 :         os << "In GC mode a call to '" << FName
    2172                 :         <<  "' decrements an object's retain count and registers the "
    2173                4:         "object with the garbage collector. ";
    2174                 : 
                        4: branch 1 taken
                        0: branch 2 not taken
    2175                4:         if (CurrV.getKind() == RefVal::Released) {
                        0: branch 1 not taken
                        4: branch 2 taken
    2176                4:           assert(CurrV.getCount() == 0);
    2177                 :           os << "Since it now has a 0 retain count the object can be "
    2178                4:           "automatically collected by the garbage collector.";
    2179                 :         }
    2180                 :         else
    2181                 :           os << "An object must have a 0 retain count to be garbage collected. "
    2182                 :           "After this call its retain count is +" << CurrV.getCount()
    2183                0:           << '.';
    2184                 :       }
    2185                 :       else
    2186                 :         os << "When GC is not enabled a call to '" << FName
    2187               10:         << "' has no effect on its argument.";
    2188                 : 
    2189                 :       // Nothing more to say.
    2190               14:       break;
    2191                 :     }
    2192                 : 
    2193                 :     // Determine if the typestate has changed.
                      191: branch 1 taken
                     1506: branch 2 taken
    2194             1697:     if (!(PrevV == CurrV))
                      120: branch 1 taken
                       33: branch 2 taken
                       34: branch 3 taken
                        4: branch 4 taken
                        0: branch 5 not taken
    2195              191:       switch (CurrV.getKind()) {
    2196                 :         case RefVal::Owned:
    2197                 :         case RefVal::NotOwned:
    2198                 : 
                       30: branch 2 taken
                       90: branch 3 taken
    2199              120:           if (PrevV.getCount() == CurrV.getCount()) {
    2200                 :             // Did an autorelease message get sent?
                        8: branch 2 taken
                       22: branch 3 taken
    2201               30:             if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount())
    2202                8:               return 0;
    2203                 : 
                        0: branch 2 not taken
                       22: branch 3 taken
    2204               22:             assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());
    2205               22:             os << "Object sent -autorelease message";
    2206               22:             break;
    2207                 :           }
    2208                 : 
                       26: branch 2 taken
                       64: branch 3 taken
    2209               90:           if (PrevV.getCount() > CurrV.getCount())
    2210               26:             os << "Reference count decremented.";
    2211                 :           else
    2212               64:             os << "Reference count incremented.";
    2213                 : 
                       84: branch 1 taken
                        6: branch 2 taken
    2214               90:           if (unsigned Count = CurrV.getCount())
    2215               84:             os << " The object now has a +" << Count << " retain count.";
    2216                 : 
                        4: branch 1 taken
                       86: branch 2 taken
    2217               90:           if (PrevV.getKind() == RefVal::Released) {
                        4: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                        4: branch 5 taken
    2218                4:             assert(TF.isGCEnabled() && CurrV.getCount() > 0);
    2219                 :             os << " The object is not eligible for garbage collection until the "
    2220                4:             "retain count reaches 0 again.";
    2221                 :           }
    2222                 : 
    2223               90:           break;
    2224                 : 
    2225                 :         case RefVal::Released:
    2226               33:           os << "Object released.";
    2227               33:           break;
    2228                 : 
    2229                 :         case RefVal::ReturnedOwned:
    2230                 :           os << "Object returned to caller as an owning reference (single retain "
    2231               34:           "count transferred to caller).";
    2232               34:           break;
    2233                 : 
    2234                 :         case RefVal::ReturnedNotOwned:
    2235                4:           os << "Object returned to caller with a +0 (non-owning) retain count.";
    2236                4:           break;
    2237                 : 
    2238                 :         default:
    2239                0:           return NULL;
    2240                 :       }
    2241                 : 
    2242                 :     // Emit any remaining diagnostics for the argument effects (if any).
                      188: branch 1 taken
                     1689: branch 2 taken
    2243             3566:     for (llvm::SmallVectorImpl<ArgEffect>::iterator I=AEffects.begin(),
    2244             1689:          E=AEffects.end(); I != E; ++I) {
    2245                 : 
    2246                 :       // A bunch of things have alternate behavior under GC.
                       24: branch 1 taken
                      164: branch 2 taken
    2247              188:       if (TF.isGCEnabled())
                        6: branch 0 taken
                        2: branch 1 taken
                        7: branch 2 taken
                        9: branch 3 taken
    2248               24:         switch (*I) {
    2249                6:           default: break;
    2250                 :           case Autorelease:
    2251                2:             os << "In GC mode an 'autorelease' has no effect.";
    2252                2:             continue;
    2253                 :           case IncRefMsg:
    2254                7:             os << "In GC mode the 'retain' message has no effect.";
    2255                7:             continue;
    2256                 :           case DecRefMsg:
    2257                9:             os << "In GC mode the 'release' message has no effect.";
    2258                9:             continue;
    2259                 :         }
    2260                 :     }
    2261                 :   } while (0);
    2262                 : 
                     1488: branch 2 taken
                      217: branch 3 taken
    2263             1705:   if (os.str().empty())
    2264             1488:     return 0; // We have nothing to say!
    2265                 : 
    2266              217:   const Stmt* S = cast<PostStmt>(N->getLocation()).getStmt();
    2267              217:   PathDiagnosticLocation Pos(S, BRC.getSourceManager());
    2268              217:   PathDiagnosticPiece* P = new PathDiagnosticEventPiece(Pos, os.str());
    2269                 : 
    2270                 :   // Add the range by scanning the children of the statement for any bindings
    2271                 :   // to Sym.
                      300: branch 4 taken
                        0: branch 5 not taken
    2272              300:   for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
    2273                 :        I!=E; ++I)
                      300: branch 2 taken
                        0: branch 3 not taken
    2274              300:     if (const Expr* Exp = dyn_cast_or_null<Expr>(*I))
                      217: branch 3 taken
                       83: branch 4 taken
    2275              300:       if (CurrSt->getSValAsScalarOrLoc(Exp).getAsLocSymbol() == Sym) {
    2276              217:         P->addRange(Exp->getSourceRange());
    2277              217:         break;
    2278                 :       }
    2279                 : 
    2280              217:   return P;
    2281                 : }
    2282                 : 
    2283                 : namespace {
    2284                 :   class FindUniqueBinding :
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                     3178: branch 6 taken
    2285             3178:   public StoreManager::BindingsHandler {
    2286                 :     SymbolRef Sym;
    2287                 :     const MemRegion* Binding;
    2288                 :     bool First;
    2289                 : 
    2290                 :   public:
    2291             3178:     FindUniqueBinding(SymbolRef sym) : Sym(sym), Binding(0), First(true) {}
    2292                 : 
    2293                 :     bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
    2294             2507:                        SVal val) {
    2295                 : 
    2296             2507:       SymbolRef SymV = val.getAsSymbol();
                     2413: branch 0 taken
                       94: branch 1 taken
                     1782: branch 2 taken
                      631: branch 3 taken
    2297             2507:       if (!SymV || SymV != Sym)
    2298             1876:         return true;
    2299                 : 
                        0: branch 0 not taken
                      631: branch 1 taken
    2300              631:       if (Binding) {
    2301                0:         First = false;
    2302                0:         return false;
    2303                 :       }
    2304                 :       else
    2305              631:         Binding = R;
    2306                 : 
    2307              631:       return true;
    2308                 :     }
    2309                 : 
                     3178: branch 0 taken
                        0: branch 1 not taken
                      631: branch 2 taken
                     2547: branch 3 taken
    2310             3178:     operator bool() { return First && Binding; }
    2311              631:     const MemRegion* getRegion() { return Binding; }
    2312                 :   };
    2313                 : }
    2314                 : 
    2315                 : static std::pair<const ExplodedNode*,const MemRegion*>
    2316                 : GetAllocationSite(GRStateManager& StateMgr, const ExplodedNode* N,
    2317              372:                   SymbolRef Sym) {
    2318                 : 
    2319                 :   // Find both first node that referred to the tracked symbol and the
    2320                 :   // memory location that value was store to.
    2321              372:   const ExplodedNode* Last = N;
    2322              372:   const MemRegion* FirstBinding = 0;
    2323                 : 
                     3550: branch 1 taken
                        0: branch 2 not taken
    2324             3550:   while (N) {
    2325             3550:     const GRState* St = N->getState();
    2326             3550:     RefBindings B = St->get<RefBindings>();
    2327                 : 
                      372: branch 1 taken
                     3178: branch 2 taken
    2328             3550:     if (!B.lookup(Sym))
    2329              372:       break;
    2330                 : 
    2331             3178:     FindUniqueBinding FB(Sym);
    2332             3178:     StateMgr.iterBindings(St, FB);
                      631: branch 1 taken
                     2547: branch 2 taken
    2333             3178:     if (FB) FirstBinding = FB.getRegion();
    2334                 : 
    2335             3178:     Last = N;
                        0: branch 1 not taken
                     3178: branch 2 taken
    2336             3178:     N = N->pred_empty() ? NULL : *(N->pred_begin());
    2337                 :   }
    2338                 : 
    2339              372:   return std::make_pair(Last, FirstBinding);
    2340                 : }
    2341                 : 
    2342                 : PathDiagnosticPiece*
    2343                 : CFRefReport::getEndPath(BugReporterContext& BRC,
    2344               55:                         const ExplodedNode* EndN) {
    2345                 :   // Tell the BugReporterContext to report cases when the tracked symbol is
    2346                 :   // assigned to different variables, etc.
    2347               55:   BRC.addNotableSymbol(Sym);
    2348               55:   return RangedBugReport::getEndPath(BRC, EndN);
    2349                 : }
    2350                 : 
    2351                 : PathDiagnosticPiece*
    2352                 : CFRefLeakReport::getEndPath(BugReporterContext& BRC,
    2353              182:                             const ExplodedNode* EndN){
    2354                 : 
    2355                 :   // Tell the BugReporterContext to report cases when the tracked symbol is
    2356                 :   // assigned to different variables, etc.
    2357              182:   BRC.addNotableSymbol(Sym);
    2358                 : 
    2359                 :   // We are reporting a leak.  Walk up the graph to get to the first node where
    2360                 :   // the symbol appeared, and also get the first VarDecl that tracked object
    2361                 :   // is stored to.
    2362              182:   const ExplodedNode* AllocNode = 0;
    2363              182:   const MemRegion* FirstBinding = 0;
    2364                 : 
    2365                 :   llvm::tie(AllocNode, FirstBinding) =
    2366              182:     GetAllocationSite(BRC.getStateManager(), EndN, Sym);
    2367                 : 
    2368                 :   // Get the allocate site.
                        0: branch 0 not taken
                      182: branch 1 taken
    2369              182:   assert(AllocNode);
    2370              182:   const Stmt* FirstStmt = cast<PostStmt>(AllocNode->getLocation()).getStmt();
    2371                 : 
    2372              182:   SourceManager& SMgr = BRC.getSourceManager();
    2373              182:   unsigned AllocLine =SMgr.getInstantiationLineNumber(FirstStmt->getLocStart());
    2374                 : 
    2375                 :   // Compute an actual location for the leak.  Sometimes a leak doesn't
    2376                 :   // occur at an actual statement (e.g., transition between blocks; end
    2377                 :   // of function) so we need to walk the graph and compute a real location.
    2378              182:   const ExplodedNode* LeakN = EndN;
    2379              182:   PathDiagnosticLocation L;
    2380                 : 
                      182: branch 0 taken
                      123: branch 1 taken
    2381              487:   while (LeakN) {
    2382              182:     ProgramPoint P = LeakN->getLocation();
    2383                 : 
                       59: branch 1 taken
                      123: branch 2 taken
    2384              182:     if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
    2385               59:       L = PathDiagnosticLocation(PS->getStmt()->getLocStart(), SMgr);
    2386               59:       break;
    2387                 :     }
                        0: branch 1 not taken
                      123: branch 2 taken
    2388              123:     else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
                        0: branch 2 not taken
                        0: branch 3 not taken
    2389                0:       if (const Stmt* Term = BE->getSrc()->getTerminator()) {
    2390                0:         L = PathDiagnosticLocation(Term->getLocStart(), SMgr);
    2391                0:         break;
    2392                 :       }
    2393                 :     }
    2394                 : 
                      123: branch 1 taken
                        0: branch 2 not taken
    2395              123:     LeakN = LeakN->succ_empty() ? 0 : *(LeakN->succ_begin());
    2396                 :   }
    2397                 : 
                      123: branch 1 taken
                       59: branch 2 taken
    2398              182:   if (!L.isValid()) {
    2399              123:     const Decl &D = EndN->getCodeDecl();
    2400              123:     L = PathDiagnosticLocation(D.getBodyRBrace(), SMgr);
    2401                 :   }
    2402                 : 
    2403              182:   std::string sbuf;
    2404              182:   llvm::raw_string_ostream os(sbuf);
    2405                 : 
    2406              182:   os << "Object allocated on line " << AllocLine;
    2407                 : 
                       40: branch 0 taken
                      142: branch 1 taken
    2408              182:   if (FirstBinding)
    2409               40:     os << " and stored into '" << FirstBinding->getString() << '\'';
    2410                 : 
    2411                 :   // Get the retain count.
    2412              182:   const RefVal* RV = EndN->getState()->get<RefBindings>(Sym);
    2413                 : 
                       16: branch 1 taken
                      166: branch 2 taken
    2414              182:   if (RV->getKind() == RefVal::ErrorLeakReturned) {
    2415                 :     // FIXME: Per comments in rdar://6320065, "create" only applies to CF
    2416                 :     // ojbects.  Only "copy", "alloc", "retain" and "new" transfer ownership
    2417                 :     // to the caller for NS objects.
    2418               16:     ObjCMethodDecl& MD = cast<ObjCMethodDecl>(EndN->getCodeDecl());
    2419                 :     os << " is returned from a method whose name ('"
    2420                 :        << MD.getSelector().getAsString()
    2421                 :     << "') does not contain 'copy' or otherwise starts with"
    2422                 :     " 'new' or 'alloc'.  This violates the naming convention rules given"
    2423               16:     " in the Memory Management Guide for Cocoa (object leaked)";
    2424                 :   }
                        6: branch 1 taken
                      160: branch 2 taken
    2425              166:   else if (RV->getKind() == RefVal::ErrorGCLeakReturned) {
    2426                6:     ObjCMethodDecl& MD = cast<ObjCMethodDecl>(EndN->getCodeDecl());
    2427                 :     os << " and returned from method '" << MD.getSelector().getAsString()
    2428                 :        << "' is potentially leaked when using garbage collection.  Callers "
    2429                 :           "of this method do not expect a returned object with a +1 retain "
    2430                 :           "count since they expect the object to be managed by the garbage "
    2431                6:           "collector";
    2432                 :   }
    2433                 :   else
    2434                 :     os << " is no longer referenced after this point and has a retain count of"
    2435              160:           " +" << RV->getCount() << " (object leaked)";
    2436                 : 
    2437              182:   return new PathDiagnosticEventPiece(L, os.str());
    2438                 : }
    2439                 : 
    2440                 : CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
    2441                 :                                  ExplodedNode *n,
    2442              190:                                  SymbolRef sym, GRExprEngine& Eng)
    2443              190: : CFRefReport(D, tf, n, sym) {
    2444                 : 
    2445                 :   // Most bug reports are cached at the location where they occured.
    2446                 :   // With leaks, we want to unique them by the location where they were
    2447                 :   // allocated, and only report a single path.  To do this, we need to find
    2448                 :   // the allocation site of a piece of tracked memory, which we do via a
    2449                 :   // call to GetAllocationSite.  This will walk the ExplodedGraph backwards.
    2450                 :   // Note that this is *not* the trimmed graph; we are guaranteed, however,
    2451                 :   // that all ancestor nodes that represent the allocation site have the
    2452                 :   // same SourceLocation.
    2453              190:   const ExplodedNode* AllocNode = 0;
    2454                 : 
    2455                 :   llvm::tie(AllocNode, AllocBinding) =  // Set AllocBinding.
    2456              190:     GetAllocationSite(Eng.getStateManager(), getEndNode(), getSymbol());
    2457                 : 
    2458                 :   // Get the SourceLocation for the allocation site.
    2459              190:   ProgramPoint P = AllocNode->getLocation();
    2460              190:   AllocSite = cast<PostStmt>(P).getStmt()->getLocStart();
    2461                 : 
    2462                 :   // Fill in the description of the bug.
    2463              190:   Description.clear();
    2464              190:   llvm::raw_string_ostream os(Description);
    2465              190:   SourceManager& SMgr = Eng.getContext().getSourceManager();
    2466              190:   unsigned AllocLine = SMgr.getInstantiationLineNumber(AllocSite);
    2467              190:   os << "Potential leak ";
                       29: branch 1 taken
                      161: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
    2468              190:   if (tf.isGCEnabled()) {
    2469               29:     os << "(when using garbage collection) ";
    2470                 :   }
    2471              190:   os << "of an object allocated on line " << AllocLine;
    2472                 : 
    2473                 :   // FIXME: AllocBinding doesn't get populated for RegionStore yet.
                       44: branch 0 taken
                      146: branch 1 taken
                      146: branch 2 taken
                      146: branch 3 taken
    2474              190:   if (AllocBinding)
    2475               44:     os << " and stored into '" << AllocBinding->getString() << '\'';
    2476              190: }
    2477                 : 
    2478                 : //===----------------------------------------------------------------------===//
    2479                 : // Main checker logic.
    2480                 : //===----------------------------------------------------------------------===//
    2481                 : 
    2482                 : /// GetReturnType - Used to get the return type of a message expression or
    2483                 : ///  function call with the intention of affixing that type to a tracked symbol.
    2484                 : ///  While the the return type can be queried directly from RetEx, when
    2485                 : ///  invoking class methods we augment to the return type to be that of
    2486                 : ///  a pointer to the class (as opposed it just being id).
    2487              899: static QualType GetReturnType(const Expr* RetE, ASTContext& Ctx) {
    2488              899:   QualType RetTy = RetE->getType();
    2489                 :   // If RetE is not a message expression just return its type.
    2490                 :   // If RetE is a message expression, return its types if it is something
    2491                 :   /// more specific than id.
                      614: branch 1 taken
                      285: branch 2 taken
    2492              899:   if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(RetE))
                      604: branch 2 taken
                       10: branch 3 taken
    2493              614:     if (const ObjCObjectPointerType *PT = RetTy->getAs<ObjCObjectPointerType>())
                      604: branch 1 taken
                        0: branch 2 not taken
                       76: branch 4 taken
                      528: branch 5 taken
                        6: branch 7 taken
                       70: branch 8 taken
                      534: branch 9 taken
                       70: branch 10 taken
    2494              604:       if (PT->isObjCQualifiedIdType() || PT->isObjCIdType() ||
    2495                 :           PT->isObjCClassType()) {
    2496                 :         // At this point we know the return type of the message expression is
    2497                 :         // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
    2498                 :         // is a call to a class method whose type we can resolve.  In such
    2499                 :         // cases, promote the return type to XXX* (where XXX is the class).
    2500              534:         const ObjCInterfaceDecl *D = ME->getClassInfo().first;
                      258: branch 0 taken
                      276: branch 1 taken
    2501              534:         return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
    2502                 :       }
    2503                 : 
    2504              365:   return RetTy;
    2505                 : }
    2506                 : 
    2507                 : void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
    2508                 :                              GRExprEngine& Eng,
    2509                 :                              GRStmtNodeBuilder& Builder,
    2510                 :                              Expr* Ex,
    2511                 :                              Expr* Receiver,
    2512                 :                              const RetainSummary& Summ,
    2513                 :                              const MemRegion *Callee,
    2514                 :                              ExprIterator arg_beg, ExprIterator arg_end,
    2515             2731:                              ExplodedNode* Pred, const GRState *state) {
    2516                 : 
    2517                 :   // Evaluate the effect of the arguments.
    2518             2731:   RefVal::Kind hasErr = (RefVal::Kind) 0;
    2519             2731:   unsigned idx = 0;
    2520             2731:   Expr* ErrorExpr = NULL;
    2521             2731:   SymbolRef ErrorSym = 0;
    2522                 : 
    2523             2731:   llvm::SmallVector<const MemRegion*, 10> RegionsToInvalidate;
    2524                 :   
                     1189: branch 1 taken
                       29: branch 2 taken
                     1263: branch 3 taken
                     2481: branch 6 taken
                     2702: branch 7 taken
    2525             7664:   for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
    2526             2481:     SVal V = state->getSValAsScalarOrLoc(*I);
    2527             2481:     SymbolRef Sym = V.getAsLocSymbol();
    2528                 : 
                      883: branch 0 taken
                     1598: branch 1 taken
    2529             2481:     if (Sym)
                      471: branch 1 taken
                      412: branch 2 taken
    2530              883:       if (RefBindings::data_type* T = state->get<RefBindings>(Sym)) {
    2531              471:         state = Update(state, Sym, *T, Summ.getArg(idx), hasErr);
                       29: branch 0 taken
                      442: branch 1 taken
    2532              471:         if (hasErr) {
    2533               29:           ErrorExpr = *I;
    2534               29:           ErrorSym = Sym;
    2535               29:           break;
    2536                 :         }
    2537             1263:         continue;
    2538                 :       }
    2539                 : 
    2540             2020:   tryAgain:
                     1118: branch 1 taken
                      902: branch 2 taken
    2541             2020:     if (isa<Loc>(V)) {
                      821: branch 1 taken
                      297: branch 2 taken
    2542             1118:       if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(&V)) {
                        8: branch 1 taken
                      813: branch 2 taken
    2543              821:         if (Summ.getArg(idx) == DoNothingByRef)
    2544                 :           continue;
    2545                 : 
    2546                 :         // Invalidate the value of the variable passed by reference.
    2547              813:         const MemRegion *R = MR->getRegion();
    2548                 : 
    2549                 :         // Are we dealing with an ElementRegion?  If the element type is
    2550                 :         // a basic integer type (e.g., char, int) and the underying region
    2551                 :         // is a variable region then strip off the ElementRegion.
    2552                 :         // FIXME: We really need to think about this for the general case
    2553                 :         //   as sometimes we are reasoning about arrays and other times
    2554                 :         //   about (char*), etc., is just a form of passing raw bytes.
    2555                 :         //   e.g., void *p = alloca(); foo((char*)p);
                      289: branch 1 taken
                      524: branch 2 taken
    2556              813:         if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
    2557                 :           // Checking for 'integral type' is probably too promiscuous, but
    2558                 :           // we'll leave it in for now until we have a systematic way of
    2559                 :           // handling all of these cases.  Eventually we need to come up
    2560                 :           // with an interface to StoreManager so that this logic can be
    2561                 :           // approriately delegated to the respective StoreManagers while
    2562                 :           // still allowing us to do checker-specific logic (e.g.,
    2563                 :           // invalidating reference counts), probably via callbacks.
                      166: branch 3 taken
                      123: branch 4 taken
    2564              289:           if (ER->getElementType()->isIntegralType()) {
    2565              166:             const MemRegion *superReg = ER->getSuperRegion();
                      134: branch 1 taken
                       32: branch 2 taken
                      122: branch 4 taken
                       12: branch 5 taken
                        0: branch 7 not taken
                      122: branch 8 taken
                       44: branch 9 taken
                      122: branch 10 taken
    2566              166:             if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
    2567                 :                 isa<ObjCIvarRegion>(superReg))
    2568               44:               R = cast<TypedRegion>(superReg);
    2569                 :           }
    2570                 :           // FIXME: What about layers of ElementRegions?
    2571                 :         }
    2572                 :         
    2573                 :         // Mark this region for invalidation.  We batch invalidate regions
    2574                 :         // below for efficiency.
    2575              813:         RegionsToInvalidate.push_back(R);
    2576                 :         continue;
    2577                 :       }
    2578                 :       else {
    2579                 :         // Nuke all other arguments passed by reference.
    2580                 :         // FIXME: is this necessary or correct? This handles the non-Region
    2581                 :         //  cases.  Is it ever valid to store to these?
    2582              297:         state = state->unbindLoc(cast<Loc>(V));
    2583                 :       }
    2584                 :     }
                       10: branch 1 taken
                      892: branch 2 taken
    2585              902:     else if (isa<nonloc::LocAsInteger>(V)) {
    2586                 :       // If we are passing a location wrapped as an integer, unwrap it and
    2587                 :       // invalidate the values referred by the location.
    2588               10:       V = cast<nonloc::LocAsInteger>(V).getLoc();
    2589               10:       goto tryAgain;
    2590                 :     }
    2591                 :   }
    2592                 :   
    2593                 :   // Block calls result in all captured values passed-via-reference to be
    2594                 :   // invalidated.
                       48: branch 1 taken
                     2683: branch 2 taken
    2595             2731:   if (const BlockDataRegion *BR = dyn_cast_or_null<BlockDataRegion>(Callee)) {
    2596               48:     RegionsToInvalidate.push_back(BR);
    2597                 :   }
    2598                 :   
    2599                 :   // Invalidate regions we designed for invalidation use the batch invalidation
    2600                 :   // API.
                      677: branch 1 taken
                     2054: branch 2 taken
    2601             2731:   if (!RegionsToInvalidate.empty()) {    
    2602                 :     // FIXME: We can have collisions on the conjured symbol if the
    2603                 :     //  expression *I also creates conjured symbols.  We probably want
    2604                 :     //  to identify conjured symbols by an expression pair: the enclosing
    2605                 :     //  expression (the context) and the expression itself.  This should
    2606                 :     //  disambiguate conjured symbols.
    2607              677:     unsigned Count = Builder.getCurrentBlockCount();
    2608              677:     StoreManager& StoreMgr = Eng.getStateManager().getStoreManager();
    2609                 : 
    2610                 :     
    2611              677:     StoreManager::InvalidatedSymbols IS;
    2612              677:     Store store = state->getStore();
    2613                 :     store = StoreMgr.InvalidateRegions(store, RegionsToInvalidate.data(),
    2614                 :                                        RegionsToInvalidate.data() +
    2615                 :                                        RegionsToInvalidate.size(),
    2616              677:                                        Ex, Count, &IS);
    2617              677:     state = state->makeWithStore(store);
                      291: branch 3 taken
                      677: branch 4 taken
    2618             1645:     for (StoreManager::InvalidatedSymbols::iterator I = IS.begin(),
    2619              677:          E = IS.end(); I!=E; ++I) {
    2620                 :         // Remove any existing reference-count binding.
    2621              291:       state = state->remove<RefBindings>(*I);
    2622              677:     }
    2623                 :   }
    2624                 : 
    2625                 :   // Evaluate the effect on the message receiver.
                     2702: branch 0 taken
                       29: branch 1 taken
                      846: branch 2 taken
                     1856: branch 3 taken
    2626             2731:   if (!ErrorExpr && Receiver) {
    2627              846:     SymbolRef Sym = state->getSValAsScalarOrLoc(Receiver).getAsLocSymbol();
                      809: branch 0 taken
                       37: branch 1 taken
    2628              846:     if (Sym) {
                      577: branch 1 taken
                      232: branch 2 taken
    2629              809:       if (const RefVal* T = state->get<RefBindings>(Sym)) {
    2630              577:         state = Update(state, Sym, *T, Summ.getReceiverEffect(), hasErr);
                       16: branch 0 taken
                      561: branch 1 taken
    2631              577:         if (hasErr) {
    2632               16:           ErrorExpr = Receiver;
    2633               16:           ErrorSym = Sym;
    2634                 :         }
    2635                 :       }
    2636                 :     }
    2637                 :   }
    2638                 : 
    2639                 :   // Process any errors.
                       45: branch 0 taken
                     2686: branch 1 taken
    2640             2731:   if (hasErr) {
    2641                 :     ProcessNonLeakError(Dst, Builder, Ex, ErrorExpr, Pred, state,
    2642               45:                         hasErr, ErrorSym);
    2643               45:     return;
    2644                 :   }
    2645                 : 
    2646                 :   // Consult the summary for the return value.
    2647             2686:   RetEffect RE = Summ.getRetEffect();
    2648                 : 
                      265: branch 1 taken
                     2421: branch 2 taken
    2649             2686:   if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
                        0: branch 0 not taken
                      265: branch 1 taken
    2650              265:     assert(Receiver);
    2651              265:     SVal V = state->getSValAsScalarOrLoc(Receiver);
    2652              265:     bool found = false;
                      245: branch 1 taken
                       20: branch 2 taken
    2653              265:     if (SymbolRef Sym = V.getAsLocSymbol())
                      212: branch 1 taken
                       33: branch 2 taken
    2654              245:       if (state->get<RefBindings>(Sym)) {
    2655              212:         found = true;
    2656              212:         RE = Summaries.getObjAllocRetEffect();
    2657                 :       }
    2658                 : 
                       53: branch 0 taken
                      212: branch 1 taken
    2659              265:     if (!found)
    2660               53:       RE = RetEffect::MakeNoRet();
    2661                 :   }
    2662                 : 
                        0: branch 1 not taken
                     1317: branch 2 taken
                      136: branch 3 taken
                      334: branch 4 taken
                      741: branch 5 taken
                      158: branch 6 taken
    2663             2686:   switch (RE.getKind()) {
    2664                 :     default:
    2665                0:       assert (false && "Unhandled RetEffect."); break;
    2666                 : 
    2667                 :     case RetEffect::NoRet: {
    2668                 :       // Make up a symbol for the return value (not reference counted).
    2669                 :       // FIXME: Most of this logic is not specific to the retain/release
    2670                 :       // checker.
    2671                 : 
    2672                 :       // FIXME: We eventually should handle structs and other compound types
    2673                 :       // that are returned by value.
    2674                 : 
    2675             1317:       QualType T = Ex->getType();
    2676                 : 
    2677                 :       // For CallExpr, use the result type to know if it returns a reference.
                     1070: branch 1 taken
                      247: branch 2 taken
    2678             1317:       if (const CallExpr *CE = dyn_cast<CallExpr>(Ex)) {
    2679             1070:         const Expr *Callee = CE->getCallee();
                     1014: branch 3 taken
                       56: branch 4 taken
    2680             1070:         if (const FunctionDecl *FD = state->getSVal(Callee).getAsFunctionDecl())
    2681             1014:           T = FD->getResultType();
    2682                 :       }
                      247: branch 1 taken
                        0: branch 2 not taken
    2683              247:       else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(Ex)) {
                      247: branch 1 taken
                        0: branch 2 not taken
    2684              247:         if (const ObjCMethodDecl *MD = ME->getMethodDecl())
    2685              247:           T = MD->getResultType();
    2686                 :       }
    2687                 : 
                      944: branch 1 taken
                      373: branch 2 taken
                      244: branch 5 taken
                      700: branch 6 taken
                      244: branch 9 taken
                        0: branch 10 not taken
                      617: branch 11 taken
                      700: branch 12 taken
    2688             1317:       if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
    2689              617:         unsigned Count = Builder.getCurrentBlockCount();
    2690              617:         ValueManager &ValMgr = Eng.getValueManager();
    2691              617:         SVal X = ValMgr.getConjuredSymbolVal(NULL, Ex, T, Count);
    2692              617:         state = state->BindExpr(Ex, X, false);
    2693                 :       }
    2694                 : 
    2695             1317:       break;
    2696                 :     }
    2697                 : 
    2698                 :     case RetEffect::Alias: {
    2699              136:       unsigned idx = RE.getIndex();
                        0: branch 1 not taken
                      136: branch 2 taken
    2700              136:       assert (arg_end >= arg_beg);
                        0: branch 1 not taken
                      136: branch 2 taken
    2701              136:       assert (idx < (unsigned) (arg_end - arg_beg));
    2702              136:       SVal V = state->getSValAsScalarOrLoc(*(arg_beg+idx));
    2703              136:       state = state->BindExpr(Ex, V, false);
    2704              136:       break;
    2705                 :     }
    2706                 : 
    2707                 :     case RetEffect::ReceiverAlias: {
                        0: branch 0 not taken
                      334: branch 1 taken
    2708              334:       assert (Receiver);
    2709              334:       SVal V = state->getSValAsScalarOrLoc(Receiver);
    2710              334:       state = state->BindExpr(Ex, V, false);
    2711              334:       break;
    2712                 :     }
    2713                 : 
    2714                 :     case RetEffect::OwnedAllocatedSymbol:
    2715                 :     case RetEffect::OwnedSymbol: {
    2716              741:       unsigned Count = Builder.getCurrentBlockCount();
    2717              741:       ValueManager &ValMgr = Eng.getValueManager();
    2718              741:       SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count);
    2719              741:       QualType RetT = GetReturnType(Ex, ValMgr.getContext());
    2720                 :       state = state->set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(),
    2721              741:                                                             RetT));
    2722              741:       state = state->BindExpr(Ex, ValMgr.makeLoc(Sym), false);
    2723                 : 
    2724                 :       // FIXME: Add a flag to the checker where allocations are assumed to
    2725                 :       // *not fail.
    2726                 : #if 0
    2727                 :       if (RE.getKind() == RetEffect::OwnedAllocatedSymbol) {
    2728                 :         bool isFeasible;
    2729                 :         state = state.Assume(loc::SymbolVal(Sym), true, isFeasible);
    2730                 :         assert(isFeasible && "Cannot assume fresh symbol is non-null.");
    2731                 :       }
    2732                 : #endif
    2733                 : 
    2734              741:       break;
    2735                 :     }
    2736                 : 
    2737                 :     case RetEffect::GCNotOwnedSymbol:
    2738                 :     case RetEffect::NotOwnedSymbol: {
    2739              158:       unsigned Count = Builder.getCurrentBlockCount();
    2740              158:       ValueManager &ValMgr = Eng.getValueManager();
    2741              158:       SymbolRef Sym = ValMgr.getConjuredSymbol(Ex, Count);
    2742              158:       QualType RetT = GetReturnType(Ex, ValMgr.getContext());
    2743                 :       state = state->set<RefBindings>(Sym, RefVal::makeNotOwned(RE.getObjKind(),
    2744              158:                                                                RetT));
    2745              158:       state = state->BindExpr(Ex, ValMgr.makeLoc(Sym), false);
    2746                 :       break;
    2747                 :     }
    2748                 :   }
    2749                 : 
    2750                 :   // Generate a sink node if we are at the end of a path.
    2751                 :   ExplodedNode *NewNode =
    2752                 :     Summ.isEndPath() ? Builder.MakeSinkNode(Dst, Ex, Pred, state)
                        8: branch 1 taken
                     2678: branch 2 taken
    2753             2686:                      : Builder.MakeNode(Dst, Ex, Pred, state);
    2754                 : 
    2755                 :   // Annotate the edge with summary we used.
                     2686: branch 0 taken
                        0: branch 1 not taken
                     2686: branch 4 taken
                       45: branch 5 taken
    2756             2686:   if (NewNode) SummaryLog[NewNode] = &Summ;
    2757                 : }
    2758                 : 
    2759                 : 
    2760                 : void CFRefCount::EvalCall(ExplodedNodeSet& Dst,
    2761                 :                           GRExprEngine& Eng,
    2762                 :                           GRStmtNodeBuilder& Builder,
    2763                 :                           CallExpr* CE, SVal L,
    2764             1520:                           ExplodedNode* Pred) {
    2765                 : 
    2766             1520:   RetainSummary *Summ = 0;
    2767                 :   
    2768                 :   // FIXME: Better support for blocks.  For now we stop tracking anything
    2769                 :   // that is passed to blocks.
    2770                 :   // FIXME: Need to handle variables that are "captured" by the block.
                       48: branch 2 taken
                     1472: branch 3 taken
    2771             1520:   if (dyn_cast_or_null<BlockDataRegion>(L.getAsRegion())) {
    2772               48:     Summ = Summaries.getPersistentStopSummary();
    2773                 :   }
    2774                 :   else {
    2775             1472:     const FunctionDecl* FD = L.getAsFunctionDecl();
    2776                 :     Summ = !FD ? Summaries.getDefaultSummary() :
                        8: branch 0 taken
                     1464: branch 1 taken
    2777             1472:                  Summaries.getSummary(const_cast<FunctionDecl*>(FD));
    2778                 :   }
    2779                 : 
                        0: branch 0 not taken
                     1520: branch 1 taken
    2780             1520:   assert(Summ);
    2781                 :   EvalSummary(Dst, Eng, Builder, CE, 0, *Summ, L.getAsRegion(),
    2782             1520:               CE->arg_begin(), CE->arg_end(), Pred, Builder.GetState(Pred));
    2783             1520: }
    2784                 : 
    2785                 : void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet& Dst,
    2786                 :                                      GRExprEngine& Eng,
    2787                 :                                      GRStmtNodeBuilder& Builder,
    2788                 :                                      ObjCMessageExpr* ME,
    2789                 :                                      ExplodedNode* Pred,
    2790             1211:                                      const GRState *state) {
    2791                 :   RetainSummary *Summ =
    2792                 :     ME->getReceiver()
    2793                 :       ? Summaries.getInstanceMethodSummary(ME, state,Pred->getLocationContext())
                      846: branch 1 taken
                      365: branch 2 taken
    2794             1211:       : Summaries.getClassMethodSummary(ME);
    2795                 : 
                        0: branch 0 not taken
                     1211: branch 1 taken
    2796             1211:   assert(Summ && "RetainSummary is null");
    2797                 :   EvalSummary(Dst, Eng, Builder, ME, ME->getReceiver(), *Summ, NULL,
    2798             1211:               ME->arg_begin(), ME->arg_end(), Pred, state);
    2799             1211: }
    2800                 : 
    2801                 : namespace {
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                      687: branch 6 taken
    2802              687: class StopTrackingCallback : public SymbolVisitor {
    2803                 :   const GRState *state;
    2804                 : public:
    2805              687:   StopTrackingCallback(const GRState *st) : state(st) {}
    2806              687:   const GRState *getState() const { return state; }
    2807                 : 
    2808              214:   bool VisitSymbol(SymbolRef sym) {
    2809              214:     state = state->remove<RefBindings>(sym);
    2810              214:     return true;
    2811                 :   }
    2812                 : };
    2813                 : } // end anonymous namespace
    2814                 : 
    2815                 : 
    2816             3973: void CFRefCount::EvalBind(GRStmtNodeBuilderRef& B, SVal location, SVal val) {
    2817                 :   // Are we storing to something that causes the value to "escape"?
    2818             3973:   bool escapes = false;
    2819                 : 
    2820                 :   // A value escapes in three possible cases (this may change):
    2821                 :   //
    2822                 :   // (1) we are binding to something that is not a memory region.
    2823                 :   // (2) we are binding to a memregion that does not have stack storage
    2824                 :   // (3) we are binding to a memregion with stack storage that the store
    2825                 :   //     does not understand.
    2826             3973:   const GRState *state = B.getState();
    2827                 : 
                       50: branch 1 taken
                     3923: branch 2 taken
    2828             3973:   if (!isa<loc::MemRegionVal>(location))
    2829               50:     escapes = true;
    2830                 :   else {
    2831             3923:     const MemRegion* R = cast<loc::MemRegionVal>(location).getRegion();
    2832             3923:     escapes = !R->hasStackStorage();
    2833                 : 
                     3568: branch 0 taken
                      355: branch 1 taken
    2834             3923:     if (!escapes) {
    2835                 :       // To test (3), generate a new state with the binding removed.  If it is
    2836                 :       // the same state, then it escapes (since the store cannot represent
    2837                 :       // the binding).
    2838             3568:       escapes = (state == (state->bindLoc(cast<Loc>(location), UnknownVal())));
    2839                 :     }
    2840                 :   }
    2841                 : 
    2842                 :   // If our store can represent the binding and we aren't storing to something
    2843                 :   // that doesn't have local storage then just return and have the simulation
    2844                 :   // state continue as is.
                     3337: branch 0 taken
                      636: branch 1 taken
    2845             3973:   if (!escapes)
    2846             3337:       return;
    2847                 : 
    2848                 :   // Otherwise, find all symbols referenced by 'val' that we are tracking
    2849                 :   // and stop tracking them.
    2850              636:   B.MakeNode(state->scanReachableSymbols<StopTrackingCallback>(val).getState());
    2851                 : }
    2852                 : 
    2853                 :  // Return statements.
    2854                 : 
    2855                 : void CFRefCount::EvalReturn(ExplodedNodeSet& Dst,
    2856                 :                             GRExprEngine& Eng,
    2857                 :                             GRStmtNodeBuilder& Builder,
    2858                 :                             ReturnStmt* S,
    2859             1305:                             ExplodedNode* Pred) {
    2860                 : 
    2861             1305:   Expr* RetE = S->getRetValue();
                      236: branch 0 taken
                     1069: branch 1 taken
    2862             1305:   if (!RetE)
    2863              236:     return;
    2864                 : 
    2865             1069:   const GRState *state = Builder.GetState(Pred);
    2866             1069:   SymbolRef Sym = state->getSValAsScalarOrLoc(RetE).getAsLocSymbol();
    2867                 : 
                      819: branch 0 taken
                      250: branch 1 taken
    2868             1069:   if (!Sym)
    2869              819:     return;
    2870                 : 
    2871                 :   // Get the reference count binding (if any).
    2872              250:   const RefVal* T = state->get<RefBindings>(Sym);
    2873                 : 
                      143: branch 0 taken
                      107: branch 1 taken
    2874              250:   if (!T)
    2875              143:     return;
    2876                 : 
    2877                 :   // Change the reference count.
    2878              107:   RefVal X = *T;
    2879                 : 
                       95: branch 1 taken
                       12: branch 2 taken
                        0: branch 3 not taken
    2880              107:   switch (X.getKind()) {
    2881                 :     case RefVal::Owned: {
    2882               95:       unsigned cnt = X.getCount();
                        0: branch 0 not taken
                       95: branch 1 taken
    2883               95:       assert (cnt > 0);
    2884               95:       X.setCount(cnt - 1);
    2885               95:       X = X ^ RefVal::ReturnedOwned;
    2886               95:       break;
    2887                 :     }
    2888                 : 
    2889                 :     case RefVal::NotOwned: {
    2890               12:       unsigned cnt = X.getCount();
                        2: branch 0 taken
                       10: branch 1 taken
    2891               12:       if (cnt) {
    2892                2:         X.setCount(cnt - 1);
    2893                2:         X = X ^ RefVal::ReturnedOwned;
    2894                 :       }
    2895                 :       else {
    2896               10:         X = X ^ RefVal::ReturnedNotOwned;
    2897                 :       }
    2898               12:       break;
    2899                 :     }
    2900                 : 
    2901                 :     default:
    2902                0:       return;
    2903                 :   }
    2904                 : 
    2905                 :   // Update the binding.
    2906              107:   state = state->set<RefBindings>(Sym, X);
    2907              107:   Pred = Builder.MakeNode(Dst, S, Pred, state);
    2908                 : 
    2909                 :   // Did we cache out?
                        0: branch 0 not taken
                      107: branch 1 taken
    2910              107:   if (!Pred)
    2911                0:     return;
    2912                 : 
    2913                 :   // Update the autorelease counts.
    2914                 :   static unsigned autoreleasetag = 0;
    2915              107:   GenericNodeBuilder Bd(Builder, S, &autoreleasetag);
    2916              107:   bool stop = false;
    2917                 :   llvm::tie(Pred, state) = HandleAutoreleaseCounts(state , Bd, Pred, Eng, Sym,
    2918              107:                                                    X, stop);
    2919                 : 
    2920                 :   // Did we cache out?
                      105: branch 0 taken
                        2: branch 1 taken
                        0: branch 2 not taken
                      105: branch 3 taken
    2921              107:   if (!Pred || stop)
    2922                2:     return;
    2923                 : 
    2924                 :   // Get the updated binding.
    2925              105:   T = state->get<RefBindings>(Sym);
                        0: branch 0 not taken
                      105: branch 1 taken
    2926              105:   assert(T);
    2927              105:   X = *T;
    2928                 : 
    2929                 :   // Any leaks or other errors?
                       81: branch 1 taken
                       24: branch 2 taken
                       73: branch 4 taken
                        8: branch 5 taken
                       73: branch 6 taken
                       32: branch 7 taken
    2930              105:   if (X.isReturnedOwned() && X.getCount() == 0) {
    2931               73:     Decl const *CD = &Pred->getCodeDecl();
                       52: branch 1 taken
                       21: branch 2 taken
    2932               73:     if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) {
    2933               52:       const RetainSummary &Summ = *Summaries.getMethodSummary(MD);
    2934               52:       RetEffect RE = Summ.getRetEffect();
    2935               52:       bool hasError = false;
    2936                 : 
                       50: branch 1 taken
                        2: branch 2 taken
    2937               52:       if (RE.getKind() != RetEffect::NoRet) {
                       10: branch 1 taken
                       40: branch 2 taken
                        6: branch 4 taken
                        4: branch 5 taken
                        6: branch 6 taken
                       44: branch 7 taken
    2938               50:         if (isGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
    2939                 :           // Things are more complicated with garbage collection.  If the
    2940                 :           // returned object is suppose to be an Objective-C object, we have
    2941                 :           // a leak (as the caller expects a GC'ed object) because no
    2942                 :           // method should return ownership unless it returns a CF object.
    2943                6:           hasError = true;
    2944                6:           X = X ^ RefVal::ErrorGCLeakReturned;
    2945                 :         }
                       16: branch 1 taken
                       28: branch 2 taken
    2946               44:         else if (!RE.isOwned()) {
    2947                 :           // Either we are using GC and the returned object is a CF type
    2948                 :           // or we aren't using GC.  In either case, we expect that the
    2949                 :           // enclosing method is expected to return ownership.
    2950               16:           hasError = true;
    2951               16:           X = X ^ RefVal::ErrorLeakReturned;
    2952                 :         }
    2953                 :       }
    2954                 : 
                       22: branch 0 taken
                       30: branch 1 taken
    2955               52:       if (hasError) {
    2956                 :         // Generate an error node.
    2957                 :         static int ReturnOwnLeakTag = 0;
    2958               22:         state = state->set<RefBindings>(Sym, X);
    2959                 :         ExplodedNode *N =
    2960                 :           Builder.generateNode(PostStmt(S, Pred->getLocationContext(),
    2961               22:                                         &ReturnOwnLeakTag), state, Pred);
                       22: branch 0 taken
                        0: branch 1 not taken
    2962               22:         if (N) {
    2963                 :           CFRefReport *report =
    2964                 :             new CFRefLeakReport(*static_cast<CFRefBug*>(leakAtReturn), *this,
    2965               22:                                 N, Sym, Eng);
    2966               22:           BR->EmitReport(report);
    2967                 :         }
    2968                 :       }
    2969                 :     }
    2970                 :   }
                       24: branch 1 taken
                        8: branch 2 taken
    2971               32:   else if (X.isReturnedNotOwned()) {
    2972               24:     Decl const *CD = &Pred->getCodeDecl();
                       14: branch 1 taken
                       10: branch 2 taken
    2973               24:     if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) {
    2974               14:       const RetainSummary &Summ = *Summaries.getMethodSummary(MD);
                        4: branch 2 taken
                       10: branch 3 taken
    2975               14:       if (Summ.getRetEffect().isOwned()) {
    2976                 :         // Trying to return a not owned object to a caller expecting an
    2977                 :         // owned object.
    2978                 : 
    2979                 :         static int ReturnNotOwnedForOwnedTag = 0;
    2980                4:         state = state->set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned);
                        4: branch 0 taken
                        0: branch 1 not taken
    2981                4:         if (ExplodedNode *N =
    2982                 :             Builder.generateNode(PostStmt(S, Pred->getLocationContext(),
    2983                 :                                           &ReturnNotOwnedForOwnedTag),
    2984                4:                                  state, Pred)) {
    2985                 :             CFRefReport *report =
    2986                 :                 new CFRefReport(*static_cast<CFRefBug*>(returnNotOwnedForOwned),
    2987                4:                                 *this, N, Sym);
    2988                4:             BR->EmitReport(report);
    2989                 :         }
    2990                 :       }
    2991                 :     }
    2992                 :   }
    2993                 : }
    2994                 : 
    2995                 : // Assumptions.
    2996                 : 
    2997                 : const GRState* CFRefCount::EvalAssume(const GRState *state,
    2998            15777:                                       SVal Cond, bool Assumption) {
    2999                 : 
    3000                 :   // FIXME: We may add to the interface of EvalAssume the list of symbols
    3001                 :   //  whose assumptions have changed.  For now we just iterate through the
    3002                 :   //  bindings and check if any of the tracked symbols are NULL.  This isn't
    3003                 :   //  too bad since the number of symbols we will track in practice are
    3004                 :   //  probably small and EvalAssume is only called at branches and a few
    3005                 :   //  other places.
    3006            15777:   RefBindings B = state->get<RefBindings>();
    3007                 : 
                    13071: branch 1 taken
                     2706: branch 2 taken
    3008            15777:   if (B.isEmpty())
    3009            13071:     return state;
    3010                 : 
    3011             2706:   bool changed = false;
    3012             2706:   RefBindings::Factory& RefBFactory = state->get_context<RefBindings>();
    3013                 : 
                     3641: branch 4 taken
                     2706: branch 5 taken
    3014             6347:   for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
    3015                 :     // Check if the symbol is null (or equal to any constant).
    3016                 :     // If this is the case, stop tracking the symbol.
                      532: branch 2 taken
                     3109: branch 3 taken
    3017             3641:     if (state->getSymVal(I.getKey())) {
    3018              532:       changed = true;
    3019              532:       B = RefBFactory.Remove(B, I.getKey());
    3020                 :     }
    3021             2706:   }
    3022                 : 
                      532: branch 0 taken
                     2174: branch 1 taken
    3023             2706:   if (changed)
    3024              532:     state = state->set<RefBindings>(B);
    3025                 : 
    3026             2706:   return state;
    3027                 : }
    3028                 : 
    3029                 : const GRState * CFRefCount::Update(const GRState * state, SymbolRef sym,
    3030                 :                               RefVal V, ArgEffect E,
    3031             1048:                               RefVal::Kind& hasErr) {
    3032                 : 
    3033                 :   // In GC mode [... release] and [... retain] do nothing.
                      571: branch 0 taken
                       52: branch 1 taken
                      361: branch 2 taken
                       64: branch 3 taken
                        0: branch 4 not taken
    3034             1048:   switch (E) {
    3035              571:     default: break;
                        9: branch 1 taken
                       43: branch 2 taken
    3036               52:     case IncRefMsg: E = isGCEnabled() ? DoNothing : IncRef; break;
                       32: branch 1 taken
                      329: branch 2 taken
    3037              361:     case DecRefMsg: E = isGCEnabled() ? DoNothing : DecRef; break;
                       37: branch 1 taken
                       27: branch 2 taken
    3038               64:     case MakeCollectable: E = isGCEnabled() ? DecRef : DoNothing; break;
    3039                 :     case NewAutoreleasePool: E = isGCEnabled() ? DoNothing :
                        0: branch 1 not taken
                        0: branch 2 not taken
    3040                0:                                                  NewAutoreleasePool; break;
    3041                 :   }
    3042                 : 
    3043                 :   // Handle all use-after-releases.
                      834: branch 1 taken
                      214: branch 2 taken
                       35: branch 4 taken
                      799: branch 5 taken
                       35: branch 6 taken
                     1013: branch 7 taken
    3044             1048:   if (!isGCEnabled() && V.getKind() == RefVal::Released) {
    3045               35:     V = V ^ RefVal::ErrorUseAfterRelease;
    3046               35:     hasErr = V.getKind();
    3047               35:     return state->set<RefBindings>(sym, V);
    3048                 :   }
    3049                 : 
                        0: branch 0 not taken
                        4: branch 1 taken
                        0: branch 2 not taken
                      108: branch 3 taken
                      214: branch 4 taken
                       90: branch 5 taken
                       28: branch 6 taken
                      111: branch 7 taken
                        0: branch 8 not taken
                      458: branch 9 taken
    3050             1013:   switch (E) {
    3051                 :     default:
    3052                0:       assert (false && "Unhandled CFRef transition.");
    3053                 : 
    3054                 :     case Dealloc:
    3055                 :       // Any use of -dealloc in GC is *bad*.
                        0: branch 1 not taken
                        4: branch 2 taken
    3056                4:       if (isGCEnabled()) {
    3057                0:         V = V ^ RefVal::ErrorDeallocGC;
    3058                0:         hasErr = V.getKind();
    3059                0:         break;
    3060                 :       }
    3061                 : 
                        0: branch 1 not taken
                        4: branch 2 taken
                        0: branch 3 not taken
    3062                4:       switch (V.getKind()) {
    3063                 :         default:
    3064                0:           assert(false && "Invalid case.");
    3065                 :         case RefVal::Owned:
    3066                 :           // The object immediately transitions to the released state.
    3067                4:           V = V ^ RefVal::Released;
    3068                4:           V.clearCounts();
    3069                4:           return state->set<RefBindings>(sym, V);
    3070                 :         case RefVal::NotOwned:
    3071                0:           V = V ^ RefVal::ErrorDeallocNotOwned;
    3072                0:           hasErr = V.getKind();
    3073                 :           break;
    3074                 :       }
    3075                0:       break;
    3076                 : 
    3077                 :     case NewAutoreleasePool:
                        0: branch 1 not taken
                        0: branch 2 not taken
    3078                0:       assert(!isGCEnabled());
    3079                0:       return state->add<AutoreleaseStack>(sym);
    3080                 : 
    3081                 :     case MayEscape:
                       48: branch 1 taken
                       60: branch 2 taken
    3082              108:       if (V.getKind() == RefVal::Owned) {
    3083               48:         V = V ^ RefVal::NotOwned;
    3084               48:         break;
    3085                 :       }
    3086                 : 
    3087                 :       // Fall-through.
    3088                 : 
    3089                 :     case DoNothingByRef:
    3090                 :     case DoNothing:
    3091              274:       return state;
    3092                 : 
    3093                 :     case Autorelease:
                       24: branch 1 taken
                       66: branch 2 taken
    3094               90:       if (isGCEnabled())
    3095               24:         return state;
    3096                 : 
    3097                 :       // Update the autorelease counts.
    3098               66:       state = SendAutorelease(state, ARCountFactory, sym);
    3099               66:       V = V.autorelease();
    3100               66:       break;
    3101                 : 
    3102                 :     case StopTracking:
    3103               28:       return state->remove<RefBindings>(sym);
    3104                 : 
    3105                 :     case IncRef:
                        0: branch 1 not taken
                      107: branch 2 taken
                        4: branch 3 taken
    3106              111:       switch (V.getKind()) {
    3107                 :         default:
    3108                0:           assert(false);
    3109                 : 
    3110                 :         case RefVal::Owned:
    3111                 :         case RefVal::NotOwned:
    3112              107:           V = V + 1;
    3113              107:           break;
    3114                 :         case RefVal::Released:
    3115                 :           // Non-GC cases are handled above.
                        0: branch 1 not taken
                        4: branch 2 taken
    3116                4:           assert(isGCEnabled());
    3117                4:           V = (V ^ RefVal::Owned) + 1;
    3118                 :           break;
    3119                 :       }
    3120              111:       break;
    3121                 : 
    3122                 :     case SelfOwn:
    3123                0:       V = V ^ RefVal::NotOwned;
    3124                 :       // Fall-through.
    3125                 :     case DecRef:
                        0: branch 1 not taken
                      412: branch 2 taken
                       46: branch 3 taken
                        0: branch 4 not taken
    3126              458:       switch (V.getKind()) {
    3127                 :         default:
    3128                 :           // case 'RefVal::Released' handled above.
    3129                0:           assert (false);
    3130                 : 
    3131                 :         case RefVal::Owned:
                        0: branch 1 not taken
                      412: branch 2 taken
    3132              412:           assert(V.getCount() > 0);
                      365: branch 1 taken
                       47: branch 2 taken
    3133              412:           if (V.getCount() == 1) V = V ^ RefVal::Released;
    3134              412:           V = V - 1;
    3135              412:           break;
    3136                 : 
    3137                 :         case RefVal::NotOwned:
                       36: branch 1 taken
                       10: branch 2 taken
    3138               46:           if (V.getCount() > 0)
    3139               36:             V = V - 1;
    3140                 :           else {
    3141               10:             V = V ^ RefVal::ErrorReleaseNotOwned;
    3142               10:             hasErr = V.getKind();
    3143                 :           }
    3144               46:           break;
    3145                 : 
    3146                 :         case RefVal::Released:
    3147                 :           // Non-GC cases are handled above.
                        0: branch 1 not taken
                        0: branch 2 not taken
    3148                0:           assert(isGCEnabled());
    3149                0:           V = V ^ RefVal::ErrorUseAfterRelease;
    3150                0:           hasErr = V.getKind();
    3151                 :           break;
    3152                 :       }
    3153                 :       break;
    3154                 :   }
    3155              683:   return state->set<RefBindings>(sym, V);
    3156                 : }
    3157                 : 
    3158                 : //===----------------------------------------------------------------------===//
    3159                 : // Handle dead symbols and end-of-path.
    3160                 : //===----------------------------------------------------------------------===//
    3161                 : 
    3162                 : std::pair<ExplodedNode*, const GRState *>
    3163                 : CFRefCount::HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilder Bd,
    3164                 :                                     ExplodedNode* Pred,
    3165                 :                                     GRExprEngine &Eng,
    3166              869:                                     SymbolRef Sym, RefVal V, bool &stop) {
    3167                 : 
    3168              869:   unsigned ACnt = V.getAutoreleaseCount();
    3169              869:   stop = false;
    3170                 : 
    3171                 :   // No autorelease counts?  Nothing to be done.
                      809: branch 0 taken
                       60: branch 1 taken
    3172              869:   if (!ACnt)
    3173              809:     return std::make_pair(Pred, state);
    3174                 : 
                       60: branch 1 taken
                        0: branch 2 not taken
    3175               60:   assert(!isGCEnabled() && "Autorelease counts in GC mode?");
    3176               60:   unsigned Cnt = V.getCount();
    3177                 : 
    3178                 :   // FIXME: Handle sending 'autorelease' to already released object.
    3179                 : 
                       16: branch 1 taken
                       44: branch 2 taken
    3180               60:   if (V.getKind() == RefVal::ReturnedOwned)
    3181               16:     ++Cnt;
    3182                 : 
                       54: branch 0 taken
                        6: branch 1 taken
    3183               60:   if (ACnt <= Cnt) {
                       46: branch 0 taken
                        8: branch 1 taken
    3184               54:     if (ACnt == Cnt) {
    3185               46:       V.clearCounts();
                       14: branch 1 taken
                       32: branch 2 taken
    3186               46:       if (V.getKind() == RefVal::ReturnedOwned)
    3187               14:         V = V ^ RefVal::ReturnedNotOwned;
    3188                 :       else
    3189               32:         V = V ^ RefVal::NotOwned;
    3190                 :     }
    3191                 :     else {
    3192                8:       V.setCount(Cnt - ACnt);
    3193                8:       V.setAutoreleaseCount(0);
    3194                 :     }
    3195               54:     state = state->set<RefBindings>(Sym, V);
    3196               54:     ExplodedNode *N = Bd.MakeNode(state, Pred);
    3197               54:     stop = (N == 0);
    3198               54:     return std::make_pair(N, state);
    3199                 :   }
    3200                 : 
    3201                 :   // Woah!  More autorelease counts then retain counts left.
    3202                 :   // Emit hard error.
    3203                6:   stop = true;
    3204                6:   V = V ^ RefVal::ErrorOverAutorelease;
    3205                6:   state = state->set<RefBindings>(Sym, V);
    3206                 : 
                        6: branch 1 taken
                        0: branch 2 not taken
    3207                6:   if (ExplodedNode *N = Bd.MakeNode(state, Pred)) {
    3208                6:     N->markAsSink();
    3209                 : 
    3210                6:     std::string sbuf;
    3211                6:     llvm::raw_string_ostream os(sbuf);
    3212                6:     os << "Object over-autoreleased: object was sent -autorelease";
                        6: branch 1 taken
                        0: branch 2 not taken
    3213                6:     if (V.getAutoreleaseCount() > 1)
    3214                6:       os << V.getAutoreleaseCount() << " times";
    3215                6:     os << " but the object has ";
                        2: branch 1 taken
                        4: branch 2 taken
    3216                6:     if (V.getCount() == 0)
    3217                2:       os << "zero (locally visible)";
    3218                 :     else
    3219                4:       os << "+" << V.getCount();
    3220                6:     os << " retain counts";
    3221                 : 
    3222                 :     CFRefReport *report =
    3223                 :       new CFRefReport(*static_cast<CFRefBug*>(overAutorelease),
    3224                6:                       *this, N, Sym, os.str());
    3225                6:     BR->EmitReport(report);
    3226                 :   }
    3227                 : 
    3228                6:   return std::make_pair((ExplodedNode*)0, state);
    3229                 : }
    3230                 : 
    3231                 : const GRState *
    3232                 : CFRefCount::HandleSymbolDeath(const GRState * state, SymbolRef sid, RefVal V,
    3233              758:                               llvm::SmallVectorImpl<SymbolRef> &Leaked) {
    3234                 : 
    3235                 :   bool hasLeak = V.isOwned() ||
                      612: branch 1 taken
                      146: branch 2 taken
                      434: branch 4 taken
                      178: branch 5 taken
                       59: branch 7 taken
                      375: branch 8 taken
                       22: branch 10 taken
                      215: branch 11 taken
    3236              758:   ((V.isNotOwned() || V.isReturnedOwned()) && V.getCount() > 0);
    3237                 : 
                      590: branch 0 taken
                      168: branch 1 taken
    3238              758:   if (!hasLeak)
    3239              590:     return state->remove<RefBindings>(sid);
    3240                 : 
    3241              168:   Leaked.push_back(sid);
    3242              168:   return state->set<RefBindings>(sid, V ^ RefVal::ErrorLeak);
    3243                 : }
    3244                 : 
    3245                 : ExplodedNode*
    3246                 : CFRefCount::ProcessLeaks(const GRState * state,
    3247                 :                          llvm::SmallVectorImpl<SymbolRef> &Leaked,
    3248                 :                          GenericNodeBuilder &Builder,
    3249                 :                          GRExprEngine& Eng,
    3250             3507:                          ExplodedNode *Pred) {
    3251                 : 
                     3359: branch 1 taken
                      148: branch 2 taken
    3252             3507:   if (Leaked.empty())
    3253             3359:     return Pred;
    3254                 : 
    3255                 :   // Generate an intermediate node representing the leak point.
    3256              148:   ExplodedNode *N = Builder.MakeNode(state, Pred);
    3257                 : 
                      148: branch 0 taken
                        0: branch 1 not taken
    3258              148:   if (N) {
                      168: branch 0 taken
                      148: branch 1 taken
    3259              316:     for (llvm::SmallVectorImpl<SymbolRef>::iterator
    3260              148:          I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
    3261                 : 
    3262                 :       CFRefBug *BT = static_cast<CFRefBug*>(Pred ? leakWithinFunction
                       53: branch 0 taken
                      115: branch 1 taken
    3263              168:                                                  : leakAtReturn);
                        0: branch 0 not taken
                      168: branch 1 taken
    3264              168:       assert(BT && "BugType not initialized.");
    3265              168:       CFRefLeakReport* report = new CFRefLeakReport(*BT, *this, N, *I, Eng);
    3266              168:       BR->EmitReport(report);
    3267                 :     }
    3268                 :   }
    3269                 : 
    3270              148:   return N;
    3271                 : }
    3272                 : 
    3273                 : void CFRefCount::EvalEndPath(GRExprEngine& Eng,
    3274             2600:                              GREndPathNodeBuilder& Builder) {
    3275                 : 
    3276             2600:   const GRState *state = Builder.getState();
    3277             2600:   GenericNodeBuilder Bd(Builder);
    3278             2600:   RefBindings B = state->get<RefBindings>();
    3279             2600:   ExplodedNode *Pred = 0;
    3280                 : 
                      390: branch 4 taken
                     2598: branch 5 taken
    3281             2988:   for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
    3282              390:     bool stop = false;
    3283                 :     llvm::tie(Pred, state) = HandleAutoreleaseCounts(state, Bd, Pred, Eng,
    3284                 :                                                      (*I).first,
    3285              390:                                                      (*I).second, stop);
    3286                 : 
                        2: branch 0 taken
                      388: branch 1 taken
    3287              390:     if (stop)
    3288                2:       return;
                     2598: branch 1 taken
                        2: branch 2 taken
                     2598: branch 4 taken
                        2: branch 5 taken
    3289             2600:   }
    3290                 : 
    3291             2598:   B = state->get<RefBindings>();
    3292             2598:   llvm::SmallVector<SymbolRef, 10> Leaked;
    3293                 : 
                      388: branch 4 taken
                     2598: branch 5 taken
    3294             2986:   for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I)
    3295             2986:     state = HandleSymbolDeath(state, (*I).first, (*I).second, Leaked);
    3296                 : 
    3297             2598:   ProcessLeaks(state, Leaked, Bd, Eng, Pred);
    3298                 : }
    3299                 : 
    3300                 : void CFRefCount::EvalDeadSymbols(ExplodedNodeSet& Dst,
    3301                 :                                  GRExprEngine& Eng,
    3302                 :                                  GRStmtNodeBuilder& Builder,
    3303                 :                                  ExplodedNode* Pred,
    3304                 :                                  Stmt* S,
    3305                 :                                  const GRState* state,
    3306              911:                                  SymbolReaper& SymReaper) {
    3307                 : 
    3308              911:   RefBindings B = state->get<RefBindings>();
    3309                 : 
    3310                 :   // Update counts from autorelease pools
                     1054: branch 3 taken
                      909: branch 4 taken
    3311             2874:   for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
    3312              911:        E = SymReaper.dead_end(); I != E; ++I) {
    3313             1054:     SymbolRef Sym = *I;
                      372: branch 1 taken
                      682: branch 2 taken
    3314             1054:     if (const RefVal* T = B.lookup(Sym)){
    3315                 :       // Use the symbol as the tag.
    3316                 :       // FIXME: This might not be as unique as we would like.
    3317              372:       GenericNodeBuilder Bd(Builder, S, Sym);
    3318              372:       bool stop = false;
    3319                 :       llvm::tie(Pred, state) = HandleAutoreleaseCounts(state, Bd, Pred, Eng,
    3320              372:                                                        Sym, *T, stop);
                        2: branch 0 taken
                      370: branch 1 taken
    3321              372:       if (stop)
    3322                2:         return;
    3323                 :     }
    3324                 :   }
    3325                 : 
    3326              909:   B = state->get<RefBindings>();
    3327              909:   llvm::SmallVector<SymbolRef, 10> Leaked;
    3328                 : 
                     1052: branch 3 taken
                      909: branch 4 taken
    3329             2870:   for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
    3330              909:        E = SymReaper.dead_end(); I != E; ++I) {
                      370: branch 2 taken
                      682: branch 3 taken
    3331             1052:       if (const RefVal* T = B.lookup(*I))
    3332              370:         state = HandleSymbolDeath(state, *I, *T, Leaked);
    3333                 :   }
    3334                 : 
    3335                 :   static unsigned LeakPPTag = 0;
    3336                 :   {
    3337              909:     GenericNodeBuilder Bd(Builder, S, &LeakPPTag);
    3338              909:     Pred = ProcessLeaks(state, Leaked, Bd, Eng, Pred);
    3339                 :   }
    3340                 : 
    3341                 :   // Did we cache out?
                        0: branch 0 not taken
                      909: branch 1 taken
    3342              909:   if (!Pred)
    3343                0:     return;
    3344                 : 
    3345                 :   // Now generate a new node that nukes the old bindings.
    3346              909:   RefBindings::Factory& F = state->get_context<RefBindings>();
    3347                 : 
                     1052: branch 3 taken
                      909: branch 4 taken
    3348             2870:   for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(),
    3349             1961:        E = SymReaper.dead_end(); I!=E; ++I) B = F.Remove(B, *I);
    3350                 : 
    3351              909:   state = state->set<RefBindings>(B);
                      909: bran