[cfe-commits] r138529 - /cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp

Jordy Rose jediknil at belkadan.com
Wed Aug 24 17:10:37 PDT 2011


Author: jrose
Date: Wed Aug 24 19:10:37 2011
New Revision: 138529

URL: http://llvm.org/viewvc/llvm-project?rev=138529&view=rev
Log:
[analyzer] Move the RetainSummaryManager from CFRefCount to RetainReleaseChecker.

Because Checkers live for an entire translation unit, this persists summary caches across multiple code bodies and avoids repeated initialization (but probably at the cost of memory). This removes the last references from RetainReleaseChecker to CFRefCount.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp?rev=138529&r1=138528&r2=138529&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Wed Aug 24 19:10:37 2011
@@ -1637,8 +1637,8 @@
                        const char* sep);
   };
 
-  RetainSummaryManager Summaries;
   const LangOptions&   LOpts;
+  const bool GCEnabled;
 
   BugType *useAfterRelease, *releaseNotOwned;
   BugType *deallocGC, *deallocNotOwned;
@@ -1648,9 +1648,8 @@
 
 public:
   CFRefCount(ASTContext &Ctx, bool gcenabled, const LangOptions& lopts)
-    : Summaries(Ctx, gcenabled, (bool)lopts.ObjCAutoRefCount),
-      LOpts(lopts), useAfterRelease(0), releaseNotOwned(0),
-      deallocGC(0), deallocNotOwned(0),
+    : LOpts(lopts), GCEnabled(gcenabled),
+      useAfterRelease(0), releaseNotOwned(0), deallocGC(0), deallocNotOwned(0),
       leakWithinFunction(0), leakAtReturn(0), overAutorelease(0),
       returnNotOwnedForOwned(0) {}
 
@@ -1659,9 +1658,6 @@
   virtual void RegisterPrinters(std::vector<ProgramState::Printer*>& Printers) {
     Printers.push_back(new BindingsPrinter());
   }
-
-  bool isGCEnabled() const { return Summaries.isGCEnabled(); }
-  bool isARCorGCEnabled() const { return Summaries.isARCorGCEnabled(); }
   
   const LangOptions& getLangOptions() const { return LOpts; }
 
@@ -2632,6 +2628,9 @@
   // This map is only used to ensure proper deletion of any allocated tags.
   mutable SymbolTagMap DeadSymbolTags;
 
+  mutable llvm::OwningPtr<RetainSummaryManager> Summaries;
+  mutable llvm::OwningPtr<RetainSummaryManager> SummariesGC;
+
   mutable ARCounts::Factory ARCountFactory;
 
   mutable SummaryLogTy SummaryLog;
@@ -2710,6 +2709,22 @@
     return isGCEnabled() || Ctx.getLangOptions().ObjCAutoRefCount;
   }
 
+  RetainSummaryManager &getSummaryManager(ASTContext &Ctx) const {
+    if (isGCEnabled()) {
+      if (!SummariesGC) {
+        bool ARCEnabled = (bool)Ctx.getLangOptions().ObjCAutoRefCount;
+        SummariesGC.reset(new RetainSummaryManager(Ctx, true, ARCEnabled));
+      }
+      return *SummariesGC;
+    } else {
+      if (!Summaries) {
+        bool ARCEnabled = (bool)Ctx.getLangOptions().ObjCAutoRefCount;
+        Summaries.reset(new RetainSummaryManager(Ctx, false, ARCEnabled));
+      }
+      return *Summaries;
+    }
+  }
+
   void checkBind(SVal loc, SVal val, CheckerContext &C) const;
   void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
   void checkPostStmt(const CastExpr *CE, CheckerContext &C) const;
@@ -2954,15 +2969,12 @@
 
 void RetainReleaseChecker::checkPostStmt(const CallExpr *CE,
                                          CheckerContext &C) const {
-  // FIXME: This goes away once the RetainSummaryManager moves to the checker.
-  CFRefCount &TF = static_cast<CFRefCount&>(C.getEngine().getTF());
-  RetainSummaryManager &Summaries = TF.Summaries;
-
   // Get the callee.
   const ProgramState *state = C.getState();
   const Expr *Callee = CE->getCallee();
   SVal L = state->getSVal(Callee);
 
+  RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
   RetainSummary *Summ = 0;
 
   // FIXME: Better support for blocks.  For now we stop tracking anything
@@ -2986,13 +2998,11 @@
 
 void RetainReleaseChecker::checkPostObjCMessage(const ObjCMessage &Msg, 
                                                 CheckerContext &C) const {
-  // FIXME: This goes away once the RetainSummaryManager moves to the checker.
-  CFRefCount &TF = static_cast<CFRefCount&>(C.getEngine().getTF());
-  RetainSummaryManager &Summaries = TF.Summaries;
-
   const ProgramState *state = C.getState();
   ExplodedNode *Pred = C.getPredecessor();
 
+  RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
+
   RetainSummary *Summ;
   if (Msg.isInstanceMessage()) {
     const LocationContext *LC = Pred->getLocationContext();
@@ -3060,13 +3070,10 @@
   RetEffect RE = Summ.getRetEffect();
 
   if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
-    if (ReceiverIsTracked) {
-      // FIXME: This goes away if the RetainSummaryManager moves to the checker.
-      CFRefCount &TF = static_cast<CFRefCount&>(C.getEngine().getTF());
-      RE = TF.Summaries.getObjAllocRetEffect();      
-    } else {
+    if (ReceiverIsTracked)
+      RE = getSummaryManager(C.getASTContext()).getObjAllocRetEffect();      
+    else
       RE = RetEffect::MakeNoRet();
-    }
   }
 
   switch (RE.getKind()) {
@@ -3467,23 +3474,21 @@
   X = *T;
 
   // Consult the summary of the enclosing method.
+  RetainSummaryManager &Summaries = getSummaryManager(C.getASTContext());
   const Decl *CD = &Pred->getCodeDecl();
 
-  // FIXME: This goes away once the RetainSummariesManager moves to the checker.
-  CFRefCount &TF = static_cast<CFRefCount&>(C.getEngine().getTF());
-
   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
     // Unlike regular functions, /all/ ObjC methods are assumed to always
     // follow Cocoa retain-count conventions, not just those with special
     // names or attributes.
-    const RetainSummary *Summ = TF.Summaries.getMethodSummary(MD);
+    const RetainSummary *Summ = Summaries.getMethodSummary(MD);
     RetEffect RE = Summ ? Summ->getRetEffect() : RetEffect::MakeNoRet();
     checkReturnWithRetEffect(S, C, Pred, RE, X, Sym, state);
   }
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {
     if (!isa<CXXMethodDecl>(FD))
-      if (const RetainSummary *Summ = TF.Summaries.getSummary(FD))
+      if (const RetainSummary *Summ = Summaries.getSummary(FD))
         checkReturnWithRetEffect(S, C, Pred, Summ->getRetEffect(), X,
                                  Sym, state);
   }
@@ -3796,7 +3801,7 @@
   // First register "return" leaks.
   const char *name = 0;
 
-  if (isGCEnabled())
+  if (GCEnabled)
     name = "Leak of returned object when using garbage collection";
   else if (getLangOptions().getGCMode() == LangOptions::HybridGC)
     name = "Leak of returned object when not using garbage collection (GC) in "
@@ -3812,7 +3817,7 @@
   BR.Register(leakAtReturn);
 
   // Second, register leaks within a function/method.
-  if (isGCEnabled())
+  if (GCEnabled)
     name = "Leak of object when using garbage collection";
   else if (getLangOptions().getGCMode() == LangOptions::HybridGC)
     name = "Leak of object when not using garbage collection (GC) in "
@@ -3835,7 +3840,7 @@
   RetainReleaseChecker *checker = 
     Eng.getCheckerManager().registerChecker<RetainReleaseChecker>();
   assert(checker);
-  checker->setGCMode(isGCEnabled() ? LangOptions::GCOnly : LangOptions::NonGC);
+  checker->setGCMode(GCEnabled ? LangOptions::GCOnly : LangOptions::NonGC);
 }
 
 TransferFuncs* ento::MakeCFRefCountTF(ASTContext &Ctx, bool GCEnabled,





More information about the cfe-commits mailing list