[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