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

Jordy Rose jediknil at belkadan.com
Wed Aug 17 14:27:39 PDT 2011


Author: jrose
Date: Wed Aug 17 16:27:39 2011
New Revision: 137874

URL: http://llvm.org/viewvc/llvm-project?rev=137874&view=rev
Log:
[analyzer] Migrate assumption and binding handling from CFRefCount to RetainReleaseChecker. This is mostly a textual move and required no supporting changes. No functionality change intended.

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=137874&r1=137873&r2=137874&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CFRefCount.cpp Wed Aug 17 16:27:39 2011
@@ -1758,8 +1758,6 @@
                                ObjCMessage msg,
                                ExplodedNode *Pred,
                                const ProgramState *state);
-  // Stores.
-  virtual void evalBind(StmtNodeBuilderRef& B, SVal location, SVal val);
 
   // End-of-path.
 
@@ -1798,13 +1796,6 @@
                                ExplodedNode *Pred,
                                RetEffect RE, RefVal X,
                                SymbolRef Sym, const ProgramState *state);
-
-
-  // Assumptions.
-
-  virtual const ProgramState *evalAssume(const ProgramState *state,
-                                         SVal condition,
-                                         bool assumption);
 };
 
 } // end anonymous namespace
@@ -2880,58 +2871,6 @@
               Pred, state);
 }
 
-namespace {
-class StopTrackingCallback : public SymbolVisitor {
-  const ProgramState *state;
-public:
-  StopTrackingCallback(const ProgramState *st) : state(st) {}
-  const ProgramState *getState() const { return state; }
-
-  bool VisitSymbol(SymbolRef sym) {
-    state = state->remove<RefBindings>(sym);
-    return true;
-  }
-};
-} // end anonymous namespace
-
-
-void CFRefCount::evalBind(StmtNodeBuilderRef& B, SVal location, SVal val) {
-  // Are we storing to something that causes the value to "escape"?
-  bool escapes = false;
-
-  // A value escapes in three possible cases (this may change):
-  //
-  // (1) we are binding to something that is not a memory region.
-  // (2) we are binding to a memregion that does not have stack storage
-  // (3) we are binding to a memregion with stack storage that the store
-  //     does not understand.
-  const ProgramState *state = B.getState();
-
-  if (!isa<loc::MemRegionVal>(location))
-    escapes = true;
-  else {
-    const MemRegion* R = cast<loc::MemRegionVal>(location).getRegion();
-    escapes = !R->hasStackStorage();
-
-    if (!escapes) {
-      // To test (3), generate a new state with the binding removed.  If it is
-      // the same state, then it escapes (since the store cannot represent
-      // the binding).
-      escapes = (state == (state->bindLoc(cast<Loc>(location), UnknownVal())));
-    }
-  }
-
-  // If our store can represent the binding and we aren't storing to something
-  // that doesn't have local storage then just return and have the simulation
-  // state continue as is.
-  if (!escapes)
-      return;
-
-  // Otherwise, find all symbols referenced by 'val' that we are tracking
-  // and stop tracking them.
-  B.MakeNode(state->scanReachableSymbols<StopTrackingCallback>(val).getState());
-}
-
  // Return statements.
 
 void CFRefCount::evalReturn(ExplodedNodeSet &Dst,
@@ -3094,41 +3033,6 @@
   }
 }
 
-// Assumptions.
-
-const ProgramState *CFRefCount::evalAssume(const ProgramState *state,
-                                           SVal Cond,
-                                           bool Assumption) {
-
-  // FIXME: We may add to the interface of evalAssume the list of symbols
-  //  whose assumptions have changed.  For now we just iterate through the
-  //  bindings and check if any of the tracked symbols are NULL.  This isn't
-  //  too bad since the number of symbols we will track in practice are
-  //  probably small and evalAssume is only called at branches and a few
-  //  other places.
-  RefBindings B = state->get<RefBindings>();
-
-  if (B.isEmpty())
-    return state;
-
-  bool changed = false;
-  RefBindings::Factory& RefBFactory = state->get_context<RefBindings>();
-
-  for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
-    // Check if the symbol is null (or equal to any constant).
-    // If this is the case, stop tracking the symbol.
-    if (state->getSymVal(I.getKey())) {
-      changed = true;
-      B = RefBFactory.remove(B, I.getKey());
-    }
-  }
-
-  if (changed)
-    state = state->set<RefBindings>(B);
-
-  return state;
-}
-
 const ProgramState * CFRefCount::Update(const ProgramState * state,
                                         SymbolRef sym,
                                         RefVal V,
@@ -3520,19 +3424,23 @@
 
 namespace {
 class RetainReleaseChecker
-  : public Checker< check::PostStmt<BlockExpr>,
+  : public Checker< check::Bind,
+                    check::PostStmt<BlockExpr>,
                     check::PostStmt<CastExpr>,
-                    check::RegionChanges > {
+                    check::RegionChanges,
+                    eval::Assume > {
 public:
     bool wantsRegionUpdate;
     
     RetainReleaseChecker() : wantsRegionUpdate(true) {}
     
-    
+    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;
 
+    const ProgramState *evalAssume(const ProgramState *state, SVal Cond,
+                                   bool Assumption) const;
+
     const ProgramState *checkRegionChanges(const ProgramState *state,
                             const StoreManager::InvalidatedSymbols *invalidated,
                                       const MemRegion * const *begin,
@@ -3544,6 +3452,92 @@
 };
 } // end anonymous namespace
 
+namespace {
+class StopTrackingCallback : public SymbolVisitor {
+  const ProgramState *state;
+public:
+  StopTrackingCallback(const ProgramState *st) : state(st) {}
+  const ProgramState *getState() const { return state; }
+
+  bool VisitSymbol(SymbolRef sym) {
+    state = state->remove<RefBindings>(sym);
+    return true;
+  }
+};
+} // end anonymous namespace
+
+
+void RetainReleaseChecker::checkBind(SVal loc, SVal val,
+                                     CheckerContext &C) const {
+  // Are we storing to something that causes the value to "escape"?
+  bool escapes = true;
+
+  // A value escapes in three possible cases (this may change):
+  //
+  // (1) we are binding to something that is not a memory region.
+  // (2) we are binding to a memregion that does not have stack storage
+  // (3) we are binding to a memregion with stack storage that the store
+  //     does not understand.
+  const ProgramState *state = C.getState();
+
+  if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) {
+    escapes = !regionLoc->getRegion()->hasStackStorage();
+
+    if (!escapes) {
+      // To test (3), generate a new state with the binding added.  If it is
+      // the same state, then it escapes (since the store cannot represent
+      // the binding).
+      escapes = (state == (state->bindLoc(*regionLoc, val)));
+    }
+  }
+
+  // If our store can represent the binding and we aren't storing to something
+  // that doesn't have local storage then just return and have the simulation
+  // state continue as is.
+  if (!escapes)
+      return;
+
+  // Otherwise, find all symbols referenced by 'val' that we are tracking
+  // and stop tracking them.
+  state = state->scanReachableSymbols<StopTrackingCallback>(val).getState();
+  C.addTransition(state);
+}
+
+// Assumptions.
+
+const ProgramState *RetainReleaseChecker::evalAssume(const ProgramState *state,
+                                                     SVal Cond,
+                                                     bool Assumption) const {
+
+  // FIXME: We may add to the interface of evalAssume the list of symbols
+  //  whose assumptions have changed.  For now we just iterate through the
+  //  bindings and check if any of the tracked symbols are NULL.  This isn't
+  //  too bad since the number of symbols we will track in practice are
+  //  probably small and evalAssume is only called at branches and a few
+  //  other places.
+  RefBindings B = state->get<RefBindings>();
+
+  if (B.isEmpty())
+    return state;
+
+  bool changed = false;
+  RefBindings::Factory &RefBFactory = state->get_context<RefBindings>();
+
+  for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+    // Check if the symbol is null (or equal to any constant).
+    // If this is the case, stop tracking the symbol.
+    if (state->getSymVal(I.getKey())) {
+      changed = true;
+      B = RefBFactory.remove(B, I.getKey());
+    }
+  }
+
+  if (changed)
+    state = state->set<RefBindings>(B);
+
+  return state;
+}
+
 const ProgramState *
 RetainReleaseChecker::checkRegionChanges(const ProgramState *state,
                             const StoreManager::InvalidatedSymbols *invalidated,





More information about the cfe-commits mailing list