]> granicus.if.org Git - clang/commitdiff
[analyzer] Move the knowledge of whether or not GC is enabled for the current analysi...
authorJordy Rose <jediknil@belkadan.com>
Fri, 2 Sep 2011 05:55:19 +0000 (05:55 +0000)
committerJordy Rose <jediknil@belkadan.com>
Fri, 2 Sep 2011 05:55:19 +0000 (05:55 +0000)
Remove TransferFuncs from ExprEngine and AnalysisConsumer.

Demote RetainReleaseChecker to a regular checker, and give it the name osx.cocoa.RetainCount (class name change coming shortly). Update tests accordingly.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138998 91177308-0d34-0410-b5e6-96231b3b80d8

30 files changed:
include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
lib/StaticAnalyzer/Checkers/Checkers.td
lib/StaticAnalyzer/Core/CFRefCount.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
test/Analysis/CFDateGC.m
test/Analysis/CFNumber.c
test/Analysis/CFRetainRelease_NSAssertionHandler.m
test/Analysis/CGColorSpace.c
test/Analysis/NSPanel.m
test/Analysis/NSString.m
test/Analysis/NSWindow.m
test/Analysis/PR2599.m
test/Analysis/cfref_PR2519.c
test/Analysis/dead-stores.m
test/Analysis/delegates.m
test/Analysis/idempotent-operations.m
test/Analysis/objc-arc.m
test/Analysis/plist-output-alternate.m
test/Analysis/pr_2542_rdar_6793404.m
test/Analysis/properties.m
test/Analysis/rdar-6562655.m
test/Analysis/refcnt_naming.m
test/Analysis/retain-release-gc-only.m
test/Analysis/retain-release-path-notes-gc.m
test/Analysis/retain-release-path-notes.m
test/Analysis/retain-release-region-store.m
test/Analysis/retain-release.m
test/Analysis/retain-release.mm

index 968b742400064b107f6a2e92535df2edfce0d2e1..cdd72880a4187c4092ee375bbdcc35f6da9ac1c4 100644 (file)
@@ -103,6 +103,10 @@ public:
     return getSValBuilder().getSymbolManager();
   }
 
+  bool isObjCGCEnabled() {
+    return Eng.isObjCGCEnabled();
+  }
+
   ExplodedNode *generateNode(bool autoTransition = true) {
     assert(statement && "Only transitions with statements currently supported");
     ExplodedNode *N = generateNodeImpl(statement, getState(), false,
index 2c0a935a024252a331540a4476580bc345f8809a..503700dc37cccbbd2f446b6b2491116dab7d8dce 100644 (file)
@@ -74,16 +74,17 @@ class ExprEngine : public SubEngine {
   // Obj-C Selectors.
   Selector* NSExceptionInstanceRaiseSelectors;
   Selector RaiseSel;
+  
+  /// Whether or not GC is enabled in this analysis.
+  bool ObjCGCEnabled;
 
   /// The BugReporter associated with this engine.  It is important that
   ///  this object be placed at the very end of member variables so that its
   ///  destructor is called before the rest of the ExprEngine is destroyed.
   GRBugReporter BR;
-  
-  llvm::OwningPtr<TransferFuncs> TF;
 
 public:
-  ExprEngine(AnalysisManager &mgr, TransferFuncs *tf);
+  ExprEngine(AnalysisManager &mgr, bool gcEnabled);
 
   ~ExprEngine();
 
@@ -111,14 +112,11 @@ public:
 
   SValBuilder &getSValBuilder() { return svalBuilder; }
 
-  TransferFuncs& getTF() { return *TF; }
-
   BugReporter& getBugReporter() { return BR; }
 
   StmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
 
-  // FIXME: Remove once TransferFuncs is no longer referenced.
-  void setTransferFunction(TransferFuncs* tf);
+  bool isObjCGCEnabled() { return ObjCGCEnabled; }
 
   /// ViewGraph - Visualize the ExplodedGraph created by executing the
   ///  simulation.
index 5c2151944449e3945861a8ae08f812a316850910..d53e0b887e75617c526a7ee3e0e102b82952e892 100644 (file)
@@ -311,6 +311,10 @@ def NSErrorChecker : Checker<"NSError">,
   HelpText<"Check usage of NSError** parameters">,
   DescFile<"NSErrorChecker.cpp">;
 
+def RetainCountChecker : Checker<"RetainCount">,
+  HelpText<"Check for leaks and improper reference count management">,
+  DescFile<"RetainCountChecker.cpp">;
+
 } // end "cocoa"
 
 let ParentPackage = CocoaExperimental in {
index a38c450148a58b5203ef940120aee4759bdef5aa..7a1c73f03dea52a7f70926927a0c401b53758eca 100644 (file)
@@ -2357,11 +2357,8 @@ class RetainReleaseChecker
   mutable SummaryLogTy SummaryLog;
   mutable bool ShouldResetSummaryLog;
 
-  LangOptions::GCMode GCMode;
-
 public:  
-  RetainReleaseChecker()
-  : ShouldResetSummaryLog(false), GCMode(LangOptions::HybridGC) {}
+  RetainReleaseChecker() : ShouldResetSummaryLog(false) {}
 
   virtual ~RetainReleaseChecker() {
     DeleteContainerSeconds(DeadSymbolTags);
@@ -2403,41 +2400,17 @@ public:
     ShouldResetSummaryLog = !SummaryLog.empty();
   }
 
-  void setGCMode(LangOptions::GCMode newGC) {
-    // FIXME: This is definitely not const behavior; its intended use is to
-    // set the GC mode for the entire coming code body. This setting will
-    // most likely live somewhere else in the future.
-    assert(newGC != LangOptions::HybridGC && "Analysis requires GC on or off.");
-    GCMode = newGC;
-  }
-
-  bool isGCEnabled() const {
-    switch (GCMode) {
-    case LangOptions::HybridGC:
-      llvm_unreachable("GC mode not set yet!");
-    case LangOptions::NonGC:
-      return false;
-    case LangOptions::GCOnly:
-      return true;
-    }
-
-    llvm_unreachable("Invalid/unknown GC mode.");
-  }
-
-  bool isARCorGCEnabled(ASTContext &Ctx) const {
-    return isGCEnabled() || Ctx.getLangOptions().ObjCAutoRefCount;
-  }
-
-  CFRefBug *getLeakWithinFunctionBug(ASTContext &Ctx) const {
-    if (isGCEnabled()) {
+  CFRefBug *getLeakWithinFunctionBug(const LangOptions &LOpts,
+                                     bool GCEnabled) const {
+    if (GCEnabled) {
       if (!leakWithinFunctionGC)
         leakWithinFunctionGC.reset(new LeakWithinFunction("Leak of object when "
                                                           "using garbage "
                                                           "collection"));
-      return &*leakWithinFunctionGC;
+      return leakWithinFunctionGC.get();
     } else {
       if (!leakWithinFunction) {
-        if (Ctx.getLangOptions().getGCMode() == LangOptions::HybridGC) {
+        if (LOpts.getGCMode() == LangOptions::HybridGC) {
           leakWithinFunction.reset(new LeakWithinFunction("Leak of object when "
                                                           "not using garbage "
                                                           "collection (GC) in "
@@ -2447,19 +2420,19 @@ public:
           leakWithinFunction.reset(new LeakWithinFunction("Leak"));
         }
       }
-      return &*leakWithinFunction;
+      return leakWithinFunction.get();
     }
   }
 
-  CFRefBug *getLeakAtReturnBug(ASTContext &Ctx) const {
-    if (isGCEnabled()) {
+  CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts, bool GCEnabled) const {
+    if (GCEnabled) {
       if (!leakAtReturnGC)
         leakAtReturnGC.reset(new LeakAtReturn("Leak of returned object when "
                                               "using garbage collection"));
-      return &*leakAtReturnGC;
+      return leakAtReturnGC.get();
     } else {
       if (!leakAtReturn) {
-        if (Ctx.getLangOptions().getGCMode() == LangOptions::HybridGC) {
+        if (LOpts.getGCMode() == LangOptions::HybridGC) {
           leakAtReturn.reset(new LeakAtReturn("Leak of returned object when "
                                               "not using garbage collection "
                                               "(GC) in dual GC/non-GC code"));
@@ -2467,26 +2440,34 @@ public:
           leakAtReturn.reset(new LeakAtReturn("Leak of returned object"));
         }
       }
-      return &*leakAtReturn;
+      return leakAtReturn.get();
     }
   }
 
-  RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const {
-    if (isGCEnabled()) {
-      if (!SummariesGC) {
-        bool ARCEnabled = (bool)Ctx.getLangOptions().ObjCAutoRefCount;
+  RetainSummaryManager &getSummaryManager(ASTContext &Ctx,
+                                          bool GCEnabled) const {
+    // FIXME: We don't support ARC being turned on and off during one analysis.
+    // (nor, for that matter, do we support changing ASTContexts)
+    bool ARCEnabled = (bool)Ctx.getLangOptions().ObjCAutoRefCount;
+    if (GCEnabled) {
+      if (!SummariesGC)
         SummariesGC.reset(new RetainSummaryManager(Ctx, true, ARCEnabled));
-      }
+      else
+        assert(SummariesGC->isARCEnabled() == ARCEnabled);
       return *SummariesGC;
     } else {
-      if (!Summaries) {
-        bool ARCEnabled = (bool)Ctx.getLangOptions().ObjCAutoRefCount;
+      if (!Summaries)
         Summaries.reset(new RetainSummaryManager(Ctx, false, ARCEnabled));
-      }
+      else
+        assert(Summaries->isARCEnabled() == ARCEnabled);
       return *Summaries;
     }
   }
 
+  RetainSummaryManager &getSummaryManager(CheckerContext &C) const {
+    return getSummaryManager(C.getASTContext(), C.isObjCGCEnabled());
+  }
+
   void printState(raw_ostream &Out, const ProgramState *State,
                   const char *NL, const char *Sep) const;
 
@@ -2524,8 +2505,8 @@ public:
   void checkEndPath(EndOfFunctionNodeBuilder &Builder, ExprEngine &Eng) const;
 
   const ProgramState *updateSymbol(const ProgramState *state, SymbolRef sym,
-                                   RefVal V, ArgEffect E,
-                                   RefVal::Kind &hasErr) const;
+                                   RefVal V, ArgEffect E, RefVal::Kind &hasErr,
+                                   CheckerContext &C) const;
 
   void processNonLeakError(const ProgramState *St, SourceRange ErrorRange,
                            RefVal::Kind ErrorKind, SymbolRef Sym,
@@ -2730,7 +2711,7 @@ void RetainReleaseChecker::checkPostStmt(const CastExpr *CE,
     return;
 
   RefVal::Kind hasErr = (RefVal::Kind) 0;
-  state = updateSymbol(state, Sym, *T, AE, hasErr);
+  state = updateSymbol(state, Sym, *T, AE, hasErr, C);
   
   if (hasErr) {
     // FIXME: If we get an error during a bridge cast, should we report it?
@@ -2748,7 +2729,7 @@ void RetainReleaseChecker::checkPostStmt(const CallExpr *CE,
   const Expr *Callee = CE->getCallee();
   SVal L = state->getSVal(Callee);
 
-  RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
+  RetainSummaryManager &Summaries = getSummaryManager(C);
   RetainSummary *Summ = 0;
 
   // FIXME: Better support for blocks.  For now we stop tracking anything
@@ -2776,7 +2757,7 @@ void RetainReleaseChecker::checkPostStmt(const CXXConstructExpr *CE,
   if (!Ctor)
     return;
 
-  RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
+  RetainSummaryManager &Summaries = getSummaryManager(C);
   RetainSummary *Summ = Summaries.getSummary(Ctor);
 
   // If we didn't get a summary, this constructor doesn't affect retain counts.
@@ -2792,7 +2773,7 @@ void RetainReleaseChecker::checkPostObjCMessage(const ObjCMessage &Msg,
   const ProgramState *state = C.getState();
   ExplodedNode *Pred = C.getPredecessor();
 
-  RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
+  RetainSummaryManager &Summaries = getSummaryManager(C);
 
   RetainSummary *Summ;
   if (Msg.isInstanceMessage()) {
@@ -2824,7 +2805,7 @@ void RetainReleaseChecker::checkSummary(const RetainSummary &Summ,
 
     if (SymbolRef Sym = V.getAsLocSymbol()) {
       if (RefBindings::data_type *T = state->get<RefBindings>(Sym)) {
-        state = updateSymbol(state, Sym, *T, Summ.getArg(idx), hasErr);
+        state = updateSymbol(state, Sym, *T, Summ.getArg(idx), hasErr, C);
         if (hasErr) {
           ErrorRange = CallOrMsg.getArgSourceRange(idx);
           ErrorSym = Sym;
@@ -2842,7 +2823,8 @@ void RetainReleaseChecker::checkSummary(const RetainSummary &Summ,
     if (SymbolRef Sym = Receiver.getAsLocSymbol()) {
       if (const RefVal *T = state->get<RefBindings>(Sym)) {
         ReceiverIsTracked = true;
-        state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(), hasErr);
+        state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
+                             hasErr, C);
         if (hasErr) {
           ErrorRange = CallOrMsg.getReceiverSourceRange();
           ErrorSym = Sym;
@@ -2862,7 +2844,7 @@ void RetainReleaseChecker::checkSummary(const RetainSummary &Summ,
 
   if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
     if (ReceiverIsTracked)
-      RE = getSummaryManager(C.getASTContext()).getObjAllocRetEffect();      
+      RE = getSummaryManager(C).getObjAllocRetEffect();      
     else
       RE = RetEffect::MakeNoRet();
   }
@@ -2940,21 +2922,24 @@ void RetainReleaseChecker::checkSummary(const RetainSummary &Summ,
 
 const ProgramState *
 RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
-                                   RefVal V, ArgEffect E,
-                                   RefVal::Kind &hasErr) const {
+                                   RefVal V, ArgEffect E, RefVal::Kind &hasErr,
+                                   CheckerContext &C) const {
   // In GC mode [... release] and [... retain] do nothing.
-  ASTContext &Ctx = state->getStateManager().getContext();
+  bool IgnoreRetainMsg = C.isObjCGCEnabled();
+  if (!IgnoreRetainMsg)
+    IgnoreRetainMsg = (bool)C.getASTContext().getLangOptions().ObjCAutoRefCount;
+
   switch (E) {
     default: break;
-    case IncRefMsg: E = isARCorGCEnabled(Ctx) ? DoNothing : IncRef; break;
-    case DecRefMsg: E = isARCorGCEnabled(Ctx) ? DoNothing : DecRef; break;
-    case MakeCollectable: E = isGCEnabled() ? DecRef : DoNothing; break;
-    case NewAutoreleasePool: E = isGCEnabled() ? DoNothing :
-                                                 NewAutoreleasePool; break;
+    case IncRefMsg: E = IgnoreRetainMsg ? DoNothing : IncRef; break;
+    case DecRefMsg: E = IgnoreRetainMsg ? DoNothing : DecRef; break;
+    case MakeCollectable: E = C.isObjCGCEnabled() ? DecRef : DoNothing; break;
+    case NewAutoreleasePool: E = C.isObjCGCEnabled() ? DoNothing :
+                                                      NewAutoreleasePool; break;
   }
 
   // Handle all use-after-releases.
-  if (!isGCEnabled() && V.getKind() == RefVal::Released) {
+  if (!C.isObjCGCEnabled() && V.getKind() == RefVal::Released) {
     V = V ^ RefVal::ErrorUseAfterRelease;
     hasErr = V.getKind();
     return state->set<RefBindings>(sym, V);
@@ -2969,7 +2954,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
 
     case Dealloc:
       // Any use of -dealloc in GC is *bad*.
-      if (isGCEnabled()) {
+      if (C.isObjCGCEnabled()) {
         V = V ^ RefVal::ErrorDeallocGC;
         hasErr = V.getKind();
         break;
@@ -2992,7 +2977,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
       break;
 
     case NewAutoreleasePool:
-      assert(!isGCEnabled());
+      assert(!C.isObjCGCEnabled());
       return state->add<AutoreleaseStack>(sym);
 
     case MayEscape:
@@ -3007,7 +2992,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
       return state;
 
     case Autorelease:
-      if (isGCEnabled())
+      if (C.isObjCGCEnabled())
         return state;
 
       // Update the autorelease counts.
@@ -3029,7 +3014,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
           break;
         case RefVal::Released:
           // Non-GC cases are handled above.
-          assert(isGCEnabled());
+          assert(C.isObjCGCEnabled());
           V = (V ^ RefVal::Owned) + 1;
           break;
       }
@@ -3065,7 +3050,7 @@ RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
 
         case RefVal::Released:
           // Non-GC cases are handled above.
-          assert(isGCEnabled());
+          assert(C.isObjCGCEnabled());
           V = V ^ RefVal::ErrorUseAfterRelease;
           hasErr = V.getKind();
           break;
@@ -3113,7 +3098,8 @@ void RetainReleaseChecker::processNonLeakError(const ProgramState *St,
 
   assert(BT);
   CFRefReport *report = new CFRefReport(*BT, C.getASTContext().getLangOptions(),
-                                        isGCEnabled(), SummaryLog, N, Sym);
+                                        C.isObjCGCEnabled(), SummaryLog,
+                                        N, Sym);
   report->addRange(ErrorRange);
   C.EmitReport(report);
 }
@@ -3271,7 +3257,7 @@ void RetainReleaseChecker::checkPreStmt(const ReturnStmt *S,
   X = *T;
 
   // Consult the summary of the enclosing method.
-  RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
+  RetainSummaryManager &Summaries = getSummaryManager(C);
   const Decl *CD = &Pred->getCodeDecl();
 
   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
@@ -3301,7 +3287,7 @@ void RetainReleaseChecker::checkReturnWithRetEffect(const ReturnStmt *S,
   if (X.isReturnedOwned() && X.getCount() == 0) {
     if (RE.getKind() != RetEffect::NoRet) {
       bool hasError = false;
-      if (isGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
+      if (C.isObjCGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
         // Things are more complicated with garbage collection.  If the
         // returned object is suppose to be an Objective-C object, we have
         // a leak (as the caller expects a GC'ed object) because no
@@ -3327,11 +3313,12 @@ void RetainReleaseChecker::checkReturnWithRetEffect(const ReturnStmt *S,
         ExplodedNode *N = Builder.generateNode(S, state, Pred,
                                                &ReturnOwnLeakTag);
         if (N) {
-          ASTContext &Ctx = C.getASTContext();
+          const LangOptions &LOpts = C.getASTContext().getLangOptions();
+          bool GCEnabled = C.isObjCGCEnabled();
           CFRefReport *report =
-            new CFRefLeakReport(*getLeakAtReturnBug(Ctx), Ctx.getLangOptions(),
-                                isGCEnabled(), SummaryLog, N, Sym, 
-                                C.getEngine());
+            new CFRefLeakReport(*getLeakAtReturnBug(LOpts, GCEnabled),
+                                LOpts, GCEnabled, SummaryLog,
+                                N, Sym, C.getEngine());
           C.EmitReport(report);
         }
       }
@@ -3353,8 +3340,8 @@ void RetainReleaseChecker::checkReturnWithRetEffect(const ReturnStmt *S,
 
         CFRefReport *report =
             new CFRefReport(*returnNotOwnedForOwned,
-                            C.getASTContext().getLangOptions(), isGCEnabled(),
-                            SummaryLog, N, Sym);
+                            C.getASTContext().getLangOptions(), 
+                            C.isObjCGCEnabled(), SummaryLog, N, Sym);
         C.EmitReport(report);
       }
     }
@@ -3377,7 +3364,7 @@ RetainReleaseChecker::handleAutoreleaseCounts(const ProgramState *state,
   if (!ACnt)
     return std::make_pair(Pred, state);
 
-  assert(!isGCEnabled() && "Autorelease counts in GC mode?");
+  assert(!Eng.isObjCGCEnabled() && "Autorelease counts in GC mode?");
   unsigned Cnt = V.getCount();
 
   // FIXME: Handle sending 'autorelease' to already released object.
@@ -3465,13 +3452,13 @@ RetainReleaseChecker::processLeaks(const ProgramState *state,
     for (SmallVectorImpl<SymbolRef>::iterator
          I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
 
-      ASTContext &Ctx = Eng.getContext();
-      CFRefBug *BT = Pred ? getLeakWithinFunctionBug(Ctx)
-                          : getLeakAtReturnBug(Ctx);
+      const LangOptions &LOpts = Eng.getContext().getLangOptions();
+      bool GCEnabled = Eng.isObjCGCEnabled();
+      CFRefBug *BT = Pred ? getLeakWithinFunctionBug(LOpts, GCEnabled)
+                          : getLeakAtReturnBug(LOpts, GCEnabled);
       assert(BT && "BugType not initialized.");
 
-      const LangOptions &LOpts = Ctx.getLangOptions();
-      CFRefLeakReport *report = new CFRefLeakReport(*BT, LOpts, isGCEnabled(), 
+      CFRefLeakReport *report = new CFRefLeakReport(*BT, LOpts, GCEnabled, 
                                                     SummaryLog, N, *I, Eng);
       Eng.getBugReporter().EmitReport(report);
     }
@@ -3638,10 +3625,24 @@ void CFRefCount::RegisterChecks(ExprEngine& Eng) {
   RetainReleaseChecker *checker = 
     Eng.getCheckerManager().registerChecker<RetainReleaseChecker>();
   assert(checker);
-  checker->setGCMode(GCEnabled ? LangOptions::GCOnly : LangOptions::NonGC);
+  //checker->setGCMode(GCEnabled ? LangOptions::GCOnly : LangOptions::NonGC);
 }
 
 TransferFuncs* ento::MakeCFRefCountTF(ASTContext &Ctx, bool GCEnabled,
                                          const LangOptions& lopts) {
   return new CFRefCount(Ctx, GCEnabled, lopts);
 }
+
+
+// FIXME: This will be unnecessary once RetainReleaseChecker is moved to
+// the Checkers library (...and renamed to RetainCountChecker).
+namespace clang {
+namespace ento {
+  void registerRetainCountChecker(CheckerManager &Mgr);  
+}
+}
+
+void ento::registerRetainCountChecker(CheckerManager &Mgr) {
+  Mgr.registerChecker<RetainReleaseChecker>();
+}
+
index 9dd288457863d177e4d4106cb5c227f75de8e48b..8b03ae223a49109dfbf9f780fe91e42a91ad9088 100644 (file)
@@ -50,7 +50,7 @@ static inline Selector GetNullarySelector(const char* name, ASTContext &Ctx) {
 // Engine construction and deletion.
 //===----------------------------------------------------------------------===//
 
-ExprEngine::ExprEngine(AnalysisManager &mgr, TransferFuncs *tf)
+ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled)
   : AMgr(mgr),
     Engine(*this),
     G(Engine.getGraph()),
@@ -63,10 +63,7 @@ ExprEngine::ExprEngine(AnalysisManager &mgr, TransferFuncs *tf)
     EntryNode(NULL), currentStmt(NULL),
     NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
     RaiseSel(GetNullarySelector("raise", getContext())),
-    BR(mgr, *this), TF(tf) {
-
-  // FIXME: Eventually remove the TF object entirely.
-  TF->RegisterChecks(*this);
+    BR(mgr, *this), ObjCGCEnabled(gcEnabled) {
   
   if (mgr.shouldEagerlyTrimExplodedGraph()) {
     // Enable eager node reclaimation when constructing the ExplodedGraph.  
index 4b5a8824ecee1bf221ae4f74d19e73baac33f7fd..7f553412a8009b432bd270ed40a4e1b6d53e341a 100644 (file)
@@ -262,8 +262,8 @@ static void FindBlocks(DeclContext *D, SmallVectorImpl<Decl*> &WL) {
       FindBlocks(DC, WL);
 }
 
-static void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
-                                 Decl *D);
+static void RunPathSensitiveChecks(AnalysisConsumer &C, AnalysisManager &mgr,
+                                   Decl *D);
 
 void AnalysisConsumer::HandleCode(Decl *D) {
 
@@ -295,7 +295,7 @@ void AnalysisConsumer::HandleCode(Decl *D) {
     if ((*WI)->hasBody()) {
       checkerMgr->runCheckersOnASTBody(*WI, *Mgr, BR);
       if (checkerMgr->hasPathSensitiveCheckers())
-        ActionObjCMemChecker(*this, *Mgr, *WI);
+        RunPathSensitiveChecks(*this, *Mgr, *WI);
     }
 }
 
@@ -303,18 +303,14 @@ void AnalysisConsumer::HandleCode(Decl *D) {
 // Path-sensitive checking.
 //===----------------------------------------------------------------------===//
 
-static void ActionExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
-                               Decl *D,
-                               TransferFuncs* tf) {
-
-  llvm::OwningPtr<TransferFuncs> TF(tf);
-
+static void ActionExprEngine(AnalysisConsumer &C, AnalysisManager &mgr,
+                             Decl *D, bool ObjCGCEnabled) {
   // Construct the analysis engine.  We first query for the LiveVariables
   // information to see if the CFG is valid.
   // FIXME: Inter-procedural analysis will need to handle invalid CFGs.
   if (!mgr.getLiveVariables(D))
     return;
-  ExprEngine Eng(mgr, TF.take());
+  ExprEngine Eng(mgr, ObjCGCEnabled);
 
   // Set the graph auditor.
   llvm::OwningPtr<ExplodedNode::Auditor> Auditor;
@@ -338,35 +334,25 @@ static void ActionExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
   Eng.getBugReporter().FlushReports();
 }
 
-static void ActionObjCMemCheckerAux(AnalysisConsumer &C, AnalysisManager& mgr,
-                                  Decl *D, bool GCEnabled) {
-
-  TransferFuncs* TF = MakeCFRefCountTF(mgr.getASTContext(),
-                                         GCEnabled,
-                                         mgr.getLangOptions());
-
-  ActionExprEngine(C, mgr, D, TF);
-}
-
-static void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
-                               Decl *D) {
-
- switch (mgr.getLangOptions().getGCMode()) {
- default:
-   assert (false && "Invalid GC mode.");
- case LangOptions::NonGC:
-   ActionObjCMemCheckerAux(C, mgr, D, false);
-   break;
-
- case LangOptions::GCOnly:
-   ActionObjCMemCheckerAux(C, mgr, D, true);
-   break;
-
- case LangOptions::HybridGC:
-   ActionObjCMemCheckerAux(C, mgr, D, false);
-   ActionObjCMemCheckerAux(C, mgr, D, true);
-   break;
- }
+static void RunPathSensitiveChecks(AnalysisConsumer &C, AnalysisManager &mgr,
+                                   Decl *D) {
+
+  switch (mgr.getLangOptions().getGCMode()) {
+  default:
+    llvm_unreachable("Invalid GC mode.");
+  case LangOptions::NonGC:
+    ActionExprEngine(C, mgr, D, false);
+    break;
+  
+  case LangOptions::GCOnly:
+    ActionExprEngine(C, mgr, D, true);
+    break;
+  
+  case LangOptions::HybridGC:
+    ActionExprEngine(C, mgr, D, false);
+    ActionExprEngine(C, mgr, D, true);
+    break;
+  }
 }
 
 //===----------------------------------------------------------------------===//
index 770a0e0276464f2a8deca604961662d114395bf2..69b99f052b0122b771983219a641778b39d0f7d4 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s  -Wno-implicit-function-declaration
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s  -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=basic -verify -fobjc-gc %s  -Wno-implicit-function-declaration
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=range -verify -fobjc-gc %s  -Wno-implicit-function-declaration
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
index 76c6bc6eb91f5f4fc1ecf8113fcb50f8f5772208..fbbe4d15f49fc75267678200727f60059f5c697a 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber -analyzer-store=region -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=basic -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=range -verify -triple x86_64-apple-darwin9 %s
 
 typedef signed long CFIndex;
 typedef const struct __CFAllocator * CFAllocatorRef;
index 35461dd0dbffd01fc1d6866f1cf4ff23cea85e0a..e0c9be1c1ebf9592ba7d1df44a17cde5e9e90a0a 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -verify %s -analyzer-constraints=basic -analyzer-store=region
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -verify %s -analyzer-constraints=range -analyzer-store=region
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -verify %s -analyzer-constraints=basic -analyzer-store=region
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -verify %s -analyzer-constraints=range -analyzer-store=region
 
 typedef struct objc_selector *SEL;
 typedef signed char BOOL;
index 4c6a03bf97c96451848a8d54ce2ee0c5446f9ee9..1bd20fa1cfa1127462539f3a31a5bd60d59a12d7 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-constraints=basic -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-constraints=range -verify %s
 
 typedef struct CGColorSpace *CGColorSpaceRef;
 extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
index d8058c0471336e4e22635b3ad60fd093b691c0b1..ac725716457f56f5fc6e25a73d44556a0276ecfc 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
 
 // BEGIN delta-debugging reduced header stuff
 
index c715f1bae9cbb85f9add79ad04ff7b2c2ddadf83..48450daa013de47ac979dd780b39081ee232e9da 100644 (file)
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
-// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
-// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,osx.AtomicCAS,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
 
 
 //===----------------------------------------------------------------------===//
index 66fb00277394b46cd06ee0f8ebda87dcb02d5c8e..495f8e19d8ef023bf277d142118f9f2731bcebfb 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-checker=deadcode.DeadStores -analyzer-store=region -analyzer-constraints=basic -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-checker=deadcode.DeadStores -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core,deadcode.DeadStores -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core,deadcode.DeadStores -analyzer-store=region -analyzer-constraints=range -verify %s
 
 // These declarations were reduced using Delta-Debugging from Foundation.h
 // on Mac OS X.  The test cases are below.
index 90c88ac11ce1750a13278ccd7f7d02748b7b4fba..5436063738a6edd531b5762ca964538d48dcce4d 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-constraints=range -analyzer-store=region -fobjc-gc -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-constraints=range -analyzer-store=region -fobjc-gc -verify %s
 
 typedef const void * CFTypeRef;
 typedef const struct __CFString * CFStringRef;
index dc760d97b2ce97e05c48ab92348bee4871efe311..5292109869162e0b1344715848633ef89ccb2b83 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=range -verify %s
 
 typedef unsigned char Boolean;
 typedef signed long CFIndex;
index 51b5858a6237d2fceeab73f9c2d2887835a4f7c6..4ed71c4e8bfa72129b72ee6d1017fe5995eaaa3c 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core -analyzer-checker=deadcode.DeadStores -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core -analyzer-checker=deadcode.DeadStores,osx.cocoa.RetainCount -verify %s
 
 typedef signed char BOOL;
 typedef unsigned int NSUInteger;
index d15a9aeaf9af20b7f392d4744f0f7e4d18ee5134..8f42b83b0eeb6dc31c5ab29985ad6852ccacdb7e 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
 
 
 //===----------------------------------------------------------------------===//
index 8f534940c9751c6198a99584bdfeffb57a3e77a0..b4765082d84a1cc3fec3fe8f2f81a00eb9cbbc69 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=deadcode.IdempotentOperations -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=deadcode.IdempotentOperations,osx.cocoa.RetainCount -verify %s
 
 typedef signed char BOOL;
 typedef unsigned long NSUInteger;
index 8e18877f29c62e72ec284e0ce7cdb77af2331ea2..507deadaefd9f951cc4975bc214be043daea3659 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-checker=deadcode -analyzer-store=region -verify -fblocks  -analyzer-opt-analyze-nested-blocks -fobjc-nonfragile-abi -fobjc-arc %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -analyzer-store=region -verify -fblocks  -analyzer-opt-analyze-nested-blocks -fobjc-nonfragile-abi -fobjc-arc %s
 
 typedef signed char BOOL;
 typedef struct _NSZone NSZone;
index 8343d4761833b93468b78b11c3da8672b50c1b74..67135fac364282caf22acafc8f337a0b652ac267 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o - %s | FileCheck %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o - %s | FileCheck %s
 
 void test_null_init(void) {
   int *p = 0;
index 69068615ca65a0000615f0b017c22724d2b4a786..d5125a649d2bbbc8be5bec7d9ae5b4516ed78ed0 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -pedantic -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -pedantic -analyzer-store=region -verify %s
 
 // BEGIN delta-debugging reduced header stuff
 
index ad9db1ad6818785addabddc5e766cdec5c51382f..6d04a4ab4e78685c55cad8ce0c6ae2d98bc96f13 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
 
 typedef signed char BOOL;
 typedef unsigned int NSUInteger;
index 62626882aa83e21212a78e96ac0fe45c41a758e9..3a592730a89738db31e2e3b7df8b599a5e1508e9 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-constraints=basic -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-constraints=basic -analyzer-store=region -verify %s
 //
 // This test case mainly checks that the retain/release checker doesn't crash
 // on this file.
index da29b1876f0087acc36a378e95932d683e87880d..aff713be49f258acf160a38320dddf876754a90f 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -verify %s
 
 typedef const struct __CFString * CFStringRef;
 typedef const struct __CFAllocator * CFAllocatorRef;
index b43b5238f71f344365c0a0d26d0b87e773a3858e..4e1b8466c322b2fe8bd07512b4ddd4fe0168f9aa 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NSAutoreleasePool -analyzer-store=region -fobjc-gc-only -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.NSAutoreleasePool -analyzer-store=region -fobjc-gc-only -fblocks -verify %s
 
 //===----------------------------------------------------------------------===//
 // Header stuff.
index a489745af2deb2c985c964fec8a0ac3f40c414f5..19e6d7b8b337ddb316d8573154d2bf086019bb44 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -analyzer-output=text -fobjc-gc-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -fobjc-gc-only -verify %s
 
 /***
 This file is for testing the path-sensitive notes for retain/release errors.
index 3c9e54bb8a3548ce4ddbe1a68ad9f5e3f1bd623c..e34942a8968c8a4adaa9a804f742317305b94a5a 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -analyzer-output=text -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s
 
 /***
 This file is for testing the path-sensitive notes for retain/release errors.
index ac2362a4a73c033e1c9d1cd1f2934dd471134de6..89950ce7cd25088d5f6714b94172bd66211cd858 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-max-loop 6 -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-max-loop 6 -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
index e2ff5c975967427bb1a65fde55b17b2c0db990f2..1e50e1ed592d67bdad29f612a3ebd54a59ca71e5 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify -x objective-c++ %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ %s
 
 #if __has_feature(attribute_ns_returns_retained)
 #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
index bdc3dc03964a40a6119b100b7aafd11f52fbe690..7c6f9e3c4aaad16f52988799ad2526e772134af1 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify %s
 
 #if __has_feature(attribute_ns_returns_retained)
 #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))