[cfe-commits] r49912 - in /cfe/trunk: include/clang/Analysis/PathSensitive/BugReporter.h include/clang/Analysis/PathSensitive/GRTransferFuncs.h lib/Analysis/CFRefCount.cpp lib/Analysis/GRExprEngine.cpp
Ted Kremenek
kremenek at apple.com
Fri Apr 18 12:23:44 PDT 2008
Author: kremenek
Date: Fri Apr 18 14:23:43 2008
New Revision: 49912
URL: http://llvm.org/viewvc/llvm-project?rev=49912&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
cfe/trunk/lib/Analysis/CFRefCount.cpp
cfe/trunk/lib/Analysis/GRExprEngine.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h?rev=49912&r1=49911&r2=49912&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h Fri Apr 18 14:23:43 2008
@@ -19,6 +19,7 @@
#include "clang/Analysis/PathSensitive/ValueState.h"
#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include <vector>
namespace clang {
@@ -41,6 +42,7 @@
virtual const char* getDescription() const { return getName(); }
virtual void EmitWarnings(BugReporter& BR) {}
+ virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes) {}
};
class BugReport {
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h?rev=49912&r1=49911&r2=49912&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Fri Apr 18 14:23:43 2008
@@ -99,11 +99,8 @@
// Assumptions.
- virtual ValueState* EvalAssume(ValueState* St, NonLVal Cond, bool Assumption){
- return St;
- }
-
- virtual ValueState* EvalAssume(ValueState* St, LVal Cond, bool Assumption) {
+ virtual ValueState* EvalAssume(GRExprEngine& Engine, ValueState* St,
+ RVal Cond, bool Assumption, bool& isFeasible) {
return St;
}
};
Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=49912&r1=49911&r2=49912&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Fri Apr 18 14:23:43 2008
@@ -693,7 +693,12 @@
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 @@
// End-of-path.
-
-
ValueState* CFRefCount::HandleSymbolDeath(ValueStateManager& VMgr,
ValueState* St, SymbolID sid,
RefVal V, bool& hasLeak) {
@@ -1066,9 +1069,9 @@
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 @@
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 @@
}
virtual void EmitWarnings(BugReporter& BR);
+ virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes);
};
//===---------===//
@@ -1465,6 +1507,12 @@
}
}
+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.
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=49912&r1=49911&r2=49912&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Fri Apr 18 14:23:43 2008
@@ -1843,7 +1843,9 @@
bool Assumption, bool& isFeasible) {
St = AssumeAux(St, Cond, Assumption, isFeasible);
- return isFeasible ? St : TF->EvalAssume(St, Cond, Assumption);
+
+ return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
+ : St;
}
ValueState* GRExprEngine::AssumeAux(ValueState* St, LVal Cond,
@@ -1881,7 +1883,9 @@
bool Assumption, bool& isFeasible) {
St = AssumeAux(St, Cond, Assumption, isFeasible);
- return isFeasible ? St : TF->EvalAssume(St, Cond, Assumption);
+
+ return isFeasible ? TF->EvalAssume(*this, St, Cond, Assumption, isFeasible)
+ : St;
}
ValueState* GRExprEngine::AssumeAux(ValueState* St, NonLVal Cond,
@@ -2258,7 +2262,7 @@
}
template <typename ITERATOR>
-static void AddSources(llvm::SmallVector<GRExprEngine::NodeTy*, 10>& Sources,
+static void AddSources(std::vector<GRExprEngine::NodeTy*>& Sources,
ITERATOR I, ITERATOR E) {
llvm::SmallPtrSet<void*,10> CachedSources;
@@ -2280,7 +2284,9 @@
void GRExprEngine::ViewGraph(bool trim) {
#ifndef NDEBUG
if (trim) {
- llvm::SmallVector<NodeTy*, 10> Src;
+ std::vector<NodeTy*> Src;
+
+ // Fixme: Migrate over to the new way of adding nodes.
AddSources(Src, null_derefs_begin(), null_derefs_end());
AddSources(Src, undef_derefs_begin(), undef_derefs_end());
AddSources(Src, explicit_bad_divides_begin(), explicit_bad_divides_end());
@@ -2289,6 +2295,11 @@
AddSources(Src, undef_arg_begin(), undef_arg_end());
AddSources(Src, undef_branches_begin(), undef_branches_end());
+ // The new way.
+ for (BugTypeSet::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I)
+ (*I)->GetErrorNodes(Src);
+
+
ViewGraph(&Src[0], &Src[0]+Src.size());
}
else {
More information about the cfe-commits
mailing list