[cfe-commits] r50194 - in /cfe/trunk: include/clang/Analysis/PathSensitive/ExplodedGraph.h lib/Analysis/BugReporter.cpp
Ted Kremenek
kremenek at apple.com
Wed Apr 23 16:02:12 PDT 2008
Author: kremenek
Date: Wed Apr 23 18:02:12 2008
New Revision: 50194
URL: http://llvm.org/viewvc/llvm-project?rev=50194&view=rev
Log:
When building PathDiagnostics for bug reports, generate a trimmed ExplodedGraph with a single path that BugReport objects can safely walk and introspect.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
cfe/trunk/lib/Analysis/BugReporter.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h?rev=50194&r1=50193&r2=50194&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h Wed Apr 23 18:02:12 2008
@@ -167,6 +167,10 @@
Profile(ID, getLocation(), getState());
}
+ void addPredecessor(ExplodedNode* V) {
+ ExplodedNodeImpl::addPredecessor(V);
+ }
+
// Iterators over successor and predecessor vertices.
typedef ExplodedNode** succ_iterator;
typedef const ExplodedNode** const_succ_iterator;
@@ -270,7 +274,8 @@
llvm::BumpPtrAllocator& getAllocator() { return Allocator; }
CFG& getCFG() { return cfg; }
ASTContext& getContext() { return Ctx; }
-
+
+ Decl& getCodeDecl() { return CodeDecl; }
const Decl& getCodeDecl() const { return CodeDecl; }
const FunctionDecl* getFunctionDecl() const {
Modified: cfe/trunk/lib/Analysis/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporter.cpp?rev=50194&r1=50193&r2=50194&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Wed Apr 23 18:02:12 2008
@@ -139,35 +139,66 @@
return NULL;
}
-void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
- BugReport& R) {
-
- ExplodedNode<ValueState>* N = R.getEndNode();
-
- if (!N)
- return;
+static std::pair<ExplodedGraph<ValueState>*, ExplodedNode<ValueState>*>
+MakeReportGraph(ExplodedGraph<ValueState>* G, ExplodedNode<ValueState>* N) {
- llvm::OwningPtr<ExplodedGraph<ValueState> > GTrim(getGraph().Trim(&N, &N+1));
-
- // Find the sink in the trimmed graph.
- // FIXME: Should we eventually have a sink iterator?
+ llvm::OwningPtr<ExplodedGraph<ValueState> > GTrim(G->Trim(&N, &N+1));
+
+ // Find the sink node in the trimmed graph.
- ExplodedNode<ValueState>* NewN = 0;
+ N = NULL;
for (ExplodedGraph<ValueState>::node_iterator
I = GTrim->nodes_begin(), E = GTrim->nodes_end(); I != E; ++I) {
if (I->isSink()) {
- NewN = &*I;
+ N = &*I;
break;
}
}
- assert (NewN);
- assert (NewN->getLocation() == N->getLocation());
-
- N = NewN;
+ assert(N);
+ // Create a new graph with a single path.
+
+ G = new ExplodedGraph<ValueState>(GTrim->getCFG(), GTrim->getCodeDecl(),
+ GTrim->getContext());
+
+
+ ExplodedNode<ValueState>* Last = 0;
+
+ while (N) {
+ ExplodedNode<ValueState>* NewN =
+ G->getNode(N->getLocation(), N->getState());
+
+ if (Last) Last->addPredecessor(NewN);
+
+ Last = NewN;
+ N = N->pred_empty() ? 0 : *(N->pred_begin());
+ }
+
+ return std::make_pair(G, Last);
+}
+
+void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
+ BugReport& R) {
+
+ ExplodedNode<ValueState>* N = R.getEndNode();
+
+ if (!N) return;
+
+ // Construct a new graph that contains only a single path from the error
+ // node to a root.
+
+ const std::pair<ExplodedGraph<ValueState>*,ExplodedNode<ValueState>*>
+ GPair = MakeReportGraph(&getGraph(), N);
+
+ llvm::OwningPtr<ExplodedGraph<ValueState> > ReportGraph(GPair.first);
+ assert(GPair.second->getLocation() == N->getLocation());
+ N = GPair.second;
+
+ // Start building the path diagnostic...
+
if (PathDiagnosticPiece* Piece = R.getEndPath(*this, N))
PD.push_back(Piece);
else
@@ -350,7 +381,8 @@
}
}
else
- if (PathDiagnosticPiece* piece = R.VisitNode(N, NextNode, *GTrim, *this))
+ if (PathDiagnosticPiece* piece = R.VisitNode(N, NextNode,
+ *ReportGraph, *this))
PD.push_front(piece);
}
}
More information about the cfe-commits
mailing list