diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-04-18 19:23:43 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-04-18 19:23:43 +0000 |
commit | cb61292aeafc1dc1bc4064fb3d2733717d1d50e5 (patch) | |
tree | a211da1ffa3b4c26fe8bc6d99c2f00fa27f49ee5 /lib/Analysis/CFRefCount.cpp | |
parent | 550a0f94938817e3550d79adcc6f1f27410f7593 (diff) |
Added "GetErrorNodes()" to BugType so that -trim-egraph can recognize errors
from registered BugTypes. This helps with debugging.
Add detection of NULL values in ref count checker; this suppresses false positives.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49912 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 1618f04359..3eb037978a 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -693,7 +693,12 @@ public: GRStmtNodeBuilder<ValueState>& Builder, ReturnStmt* S, ExplodedNode<ValueState>* Pred); - + + // Assumptions. + + virtual ValueState* EvalAssume(GRExprEngine& Engine, ValueState* St, + RVal Cond, bool Assumption, bool& isFeasible); + // Error iterators. typedef UseAfterReleasesTy::iterator use_after_iterator; @@ -1029,8 +1034,6 @@ ValueState* CFRefCount::NukeBinding(ValueStateManager& VMgr, ValueState* St, // End-of-path. - - ValueState* CFRefCount::HandleSymbolDeath(ValueStateManager& VMgr, ValueState* St, SymbolID sid, RefVal V, bool& hasLeak) { @@ -1066,9 +1069,9 @@ void CFRefCount::EvalEndPath(GRExprEngine& Eng, ExplodedNode<ValueState>* N = Builder.MakeNode(St); - if (!N) + if (!N || Leaked.empty()) return; - + std::vector<SymbolID>*& LeaksAtNode = Leaks[N]; assert (!LeaksAtNode); LeaksAtNode = new std::vector<SymbolID>(); @@ -1138,6 +1141,44 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<ValueState>& Dst, Builder.MakeNode(Dst, S, Pred, StateMgr.getPersistentState(StImpl)); } +// Assumptions. + +ValueState* CFRefCount::EvalAssume(GRExprEngine& Eng, ValueState* St, + RVal Cond, bool Assumption, + bool& isFeasible) { + + // 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 = GetRefBindings(*St); + + if (B.isEmpty()) + return St; + + bool changed = false; + + 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 (St->getSymVal(I.getKey())) { + changed = true; + B = RefBFactory.Remove(B, I.getKey()); + } + } + + if (!changed) + return St; + + ValueState StImpl = *St; + StImpl.CheckerState = B.getRoot(); + return Eng.getStateManager().getPersistentState(StImpl); +} CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E, @@ -1280,6 +1321,7 @@ namespace { } virtual void EmitWarnings(BugReporter& BR); + virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes); }; //===---------===// @@ -1465,6 +1507,12 @@ void Leak::EmitWarnings(BugReporter& BR) { } } +void Leak::GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes) { + for (CFRefCount::leaks_iterator I=TF.leaks_begin(), E=TF.leaks_end(); + I!=E; ++I) + Nodes.push_back(I->first); +} + //===----------------------------------------------------------------------===// // Transfer function creation for external clients. //===----------------------------------------------------------------------===// |