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

Jordy Rose jediknil at belkadan.com
Wed Aug 24 13:33:55 PDT 2011


Author: jrose
Date: Wed Aug 24 15:33:55 2011
New Revision: 138476

URL: http://llvm.org/viewvc/llvm-project?rev=138476&view=rev
Log:
[analyzer] Copy GC mode setting from CFRefCount to RetainReleaseChecker in preparation for getting rid of CFRefCount.

This is a little hacky for now but will get better once we decide the best way to handle this.

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=138476&r1=138475&r2=138476&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Wed Aug 24 15:33:55 2011
@@ -2632,8 +2632,11 @@
   mutable SummaryLogTy SummaryLog;
   mutable bool ShouldResetSummaryLog;
 
+  LangOptions::GCMode GCMode;
+
 public:  
-  RetainReleaseChecker() : ShouldResetSummaryLog(false) {}
+  RetainReleaseChecker()
+  : ShouldResetSummaryLog(false), GCMode(LangOptions::HybridGC) {}
 
   virtual ~RetainReleaseChecker() {
     DeleteContainerSeconds(DeadSymbolTags);
@@ -2675,6 +2678,30 @@
     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!");
+      return true;
+    case LangOptions::NonGC:
+      return false;
+    case LangOptions::GCOnly:
+      return true;
+    }
+  }
+
+  bool isARCorGCEnabled(ASTContext &Ctx) const {
+    return isGCEnabled() || Ctx.getLangOptions().ObjCAutoRefCount;
+  }
+
   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;
@@ -3109,23 +3136,19 @@
 RetainReleaseChecker::updateSymbol(const ProgramState *state, SymbolRef sym,
                                    RefVal V, ArgEffect E,
                                    RefVal::Kind &hasErr) const {
-  // FIXME: This will go away when the ARC/GC state moves to the checker.
-  ExprEngine *Eng = 
-    static_cast<ExprEngine*>(state->getStateManager().getOwningEngine());
-  CFRefCount &TF = static_cast<CFRefCount&>(Eng->getTF());
-
   // In GC mode [... release] and [... retain] do nothing.
+  ASTContext &Ctx = state->getStateManager().getContext();
   switch (E) {
     default: break;
-    case IncRefMsg: E = TF.isARCorGCEnabled() ? DoNothing : IncRef; break;
-    case DecRefMsg: E = TF.isARCorGCEnabled() ? DoNothing : DecRef; break;
-    case MakeCollectable: E = TF.isGCEnabled() ? DecRef : DoNothing; break;
-    case NewAutoreleasePool: E = TF.isGCEnabled() ? DoNothing :
-                                                    NewAutoreleasePool; 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;
   }
 
   // Handle all use-after-releases.
-  if (!TF.isGCEnabled() && V.getKind() == RefVal::Released) {
+  if (!isGCEnabled() && V.getKind() == RefVal::Released) {
     V = V ^ RefVal::ErrorUseAfterRelease;
     hasErr = V.getKind();
     return state->set<RefBindings>(sym, V);
@@ -3140,7 +3163,7 @@
 
     case Dealloc:
       // Any use of -dealloc in GC is *bad*.
-      if (TF.isGCEnabled()) {
+      if (isGCEnabled()) {
         V = V ^ RefVal::ErrorDeallocGC;
         hasErr = V.getKind();
         break;
@@ -3163,7 +3186,7 @@
       break;
 
     case NewAutoreleasePool:
-      assert(!TF.isGCEnabled());
+      assert(!isGCEnabled());
       return state->add<AutoreleaseStack>(sym);
 
     case MayEscape:
@@ -3178,7 +3201,7 @@
       return state;
 
     case Autorelease:
-      if (TF.isGCEnabled())
+      if (isGCEnabled())
         return state;
 
       // Update the autorelease counts.
@@ -3200,7 +3223,7 @@
           break;
         case RefVal::Released:
           // Non-GC cases are handled above.
-          assert(TF.isGCEnabled());
+          assert(isGCEnabled());
           V = (V ^ RefVal::Owned) + 1;
           break;
       }
@@ -3236,7 +3259,7 @@
 
         case RefVal::Released:
           // Non-GC cases are handled above.
-          assert(TF.isGCEnabled());
+          assert(isGCEnabled());
           V = V ^ RefVal::ErrorUseAfterRelease;
           hasErr = V.getKind();
           break;
@@ -3472,7 +3495,7 @@
   if (X.isReturnedOwned() && X.getCount() == 0) {
     if (RE.getKind() != RetEffect::NoRet) {
       bool hasError = false;
-      if (TF.isGCEnabled() && RE.getObjKind() == RetEffect::ObjC) {
+      if (isGCEnabled() && 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
@@ -3548,7 +3571,7 @@
   if (!ACnt)
     return std::make_pair(Pred, state);
 
-  assert(!TF.isGCEnabled() && "Autorelease counts in GC mode?");
+  assert(!isGCEnabled() && "Autorelease counts in GC mode?");
   unsigned Cnt = V.getCount();
 
   // FIXME: Handle sending 'autorelease' to already released object.
@@ -3800,7 +3823,10 @@
   // over time.
   // FIXME: HACK! Remove TransferFuncs and turn all of CFRefCount into fully
   // using the checker mechanism.
-  Eng.getCheckerManager().registerChecker<RetainReleaseChecker>();
+  RetainReleaseChecker *checker = 
+    Eng.getCheckerManager().registerChecker<RetainReleaseChecker>();
+  assert(checker);
+  checker->setGCMode(isGCEnabled() ? LangOptions::GCOnly : LangOptions::NonGC);
 }
 
 TransferFuncs* ento::MakeCFRefCountTF(ASTContext &Ctx, bool GCEnabled,





More information about the cfe-commits mailing list