diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-06-17 19:14:06 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-06-17 19:14:06 +0000 |
commit | 3802fedfe49f13c770f362f81afc4454ab188f3a (patch) | |
tree | 5870efcb57a2cfa995f674cc7cd985ff2568c268 /clang/lib/Analysis/BugReporter.cpp | |
parent | 90ada832be86aef1a9329475485f868ef73af455 (diff) | |
download | bcm5719-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.cpp | 26 |
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); |