summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/BugReporter.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-06-17 19:14:06 +0000
committerTed Kremenek <kremenek@apple.com>2008-06-17 19:14:06 +0000
commit3802fedfe49f13c770f362f81afc4454ab188f3a (patch)
tree5870efcb57a2cfa995f674cc7cd985ff2568c268 /clang/lib/Analysis/BugReporter.cpp
parent90ada832be86aef1a9329475485f868ef73af455 (diff)
downloadbcm5719-llvm-3802fedfe49f13c770f362f81afc4454ab188f3a.tar.gz
bcm5719-llvm-3802fedfe49f13c770f362f81afc4454ab188f3a.zip
Fix non-termination bug reported by Thomas Clement!
llvm-svn: 52426
Diffstat (limited to 'clang/lib/Analysis/BugReporter.cpp')
-rw-r--r--clang/lib/Analysis/BugReporter.cpp26
1 files changed, 25 insertions, 1 deletions
diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp
index cccd71bd967..141ee48aa05 100644
--- a/clang/lib/Analysis/BugReporter.cpp
+++ b/clang/lib/Analysis/BugReporter.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/Expr.h"
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Analysis/PathDiagnostic.h"
+#include "llvm/ADT/DenseSet.h"
#include <sstream>
using namespace clang;
@@ -205,8 +206,15 @@ MakeReportGraph(ExplodedGraph<ValueState>* G, ExplodedNode<ValueState>* N) {
ExplodedNode<ValueState> *Last = 0, *First = 0;
+
+ // Sometimes TrimGraph can contain a cycle because there are multiple BFS
+ // paths with the same length. We mark the nodes we visit so that we
+ // don't get stuck in a cycle.
+ llvm::DenseSet<void*> Visited;
while (N) {
+ Visited.insert(N);
+
ExplodedNode<ValueState>* NewN =
G->getNode(N->getLocation(), N->getState());
@@ -214,7 +222,23 @@ MakeReportGraph(ExplodedGraph<ValueState>* G, ExplodedNode<ValueState>* N) {
if (Last) Last->addPredecessor(NewN);
Last = NewN;
- N = N->pred_empty() ? 0 : *(N->pred_begin());
+
+ if (N->pred_empty())
+ break;
+
+ ExplodedNode<ValueState>::pred_iterator PI = N->pred_begin();
+ ExplodedNode<ValueState>::pred_iterator PE = N->pred_end();
+ N = 0;
+
+ // Look for the first predecessor that we have not already visited.
+
+ for (; PI != PE; ++PI)
+ if (!Visited.count(*PI)) {
+ N = *PI;
+ break;
+ }
+
+ assert (N && "All predecessors involved in a cycle!");
}
return std::make_pair(G, First);
OpenPOWER on IntegriCloud