[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