[cfe-commits] r151663 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h lib/StaticAnalyzer/Core/BugReporter.cpp lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Ted Kremenek kremenek at apple.com
Tue Feb 28 15:06:21 PST 2012


Author: kremenek
Date: Tue Feb 28 17:06:21 2012
New Revision: 151663

URL: http://llvm.org/viewvc/llvm-project?rev=151663&view=rev
Log:
[analyzer diagnostics] start prototyping stripping PathDiagnostics of unnecessary cruft caused by path inlining.

This introduces a concept of a "prunable" PathDiagnosticEvent.  Currently this is a flag, but
we may evolve the concept to make this more dynamically inferred.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
    cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h?rev=151663&r1=151662&r2=151663&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h Tue Feb 28 17:06:21 2012
@@ -132,11 +132,17 @@
     ID.AddPointer(&x);
   }
 
+  
   virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
                                          const ExplodedNode *Prev,
                                          BugReporterContext &BRC,
                                          BugReport &BR);
 
+  PathDiagnosticPiece *VisitNodeImpl(const ExplodedNode *N,
+                                     const ExplodedNode *Prev,
+                                     BugReporterContext &BRC,
+                                     BugReport &BR);
+  
   PathDiagnosticPiece *VisitTerminator(const Stmt *Term,
                                        const ExplodedNode *N,
                                        const CFGBlock *srcBlk,

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h?rev=151663&r1=151662&r2=151663&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h Tue Feb 28 17:06:21 2012
@@ -353,14 +353,18 @@
 };
 
 class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
-
+  bool IsPrunable;
 public:
   PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
                            StringRef s, bool addPosRange = true)
-    : PathDiagnosticSpotPiece(pos, s, Event, addPosRange) {}
+    : PathDiagnosticSpotPiece(pos, s, Event, addPosRange),
+      IsPrunable(false) {}
 
   ~PathDiagnosticEventPiece();
 
+  void setPrunable(bool isPrunable) { IsPrunable = isPrunable; }
+  bool isPrunable() const { return IsPrunable; }
+  
   static inline bool classof(const PathDiagnosticPiece *P) {
     return P->getKind() == Event;
   }
@@ -527,7 +531,7 @@
 
   void pushActivePath(PathPieces *p) { pathStack.push_back(p); }
   void popActivePath() { if (!pathStack.empty()) pathStack.pop_back(); }
-
+  
   PathDiagnostic();
   PathDiagnostic(StringRef bugtype, StringRef desc,
                  StringRef category);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=151663&r1=151662&r2=151663&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Tue Feb 28 17:06:21 2012
@@ -111,6 +111,51 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Diagnostic cleanup.
+//===----------------------------------------------------------------------===//
+
+/// Recursively scan through a path and prune out calls and macros pieces
+/// that aren't needed.  Return true if afterwards the path contains
+/// "interesting stuff" which means it should be pruned from the parent path.
+static bool RemoveUneededCalls(PathPieces &pieces) {
+  bool containsSomethingInteresting = false;
+  const unsigned N = pieces.size();
+  
+  for (unsigned i = 0 ; i < N ; ++i) {
+    // Remove the front piece from the path.  If it is still something we
+    // want to keep once we are done, we will push it back on the end.
+    IntrusiveRefCntPtr<PathDiagnosticPiece> piece(pieces.front());
+    pieces.pop_front();
+    
+    if (PathDiagnosticCallPiece *call =
+        dyn_cast<PathDiagnosticCallPiece>(piece)) {      
+      // Recursively clean out the subclass.  Keep this call around if
+      // it contains any informative diagnostics.
+      if (!RemoveUneededCalls(call->path))
+        continue;
+      containsSomethingInteresting = true;
+    }
+    else if (PathDiagnosticMacroPiece *macro =
+             dyn_cast<PathDiagnosticMacroPiece>(piece)) {
+      if (!RemoveUneededCalls(macro->subPieces))
+        continue;
+      containsSomethingInteresting = true;
+    }
+    else if (PathDiagnosticEventPiece *event =
+             dyn_cast<PathDiagnosticEventPiece>(piece)) {
+      // We never throw away an event, but we do throw it away wholesale
+      // as part of a path if we throw the entire path away.
+      if (!event->isPrunable())
+        containsSomethingInteresting = true;
+    }
+    
+    pieces.push_back(piece);
+  }
+  
+  return containsSomethingInteresting;
+}
+
+//===----------------------------------------------------------------------===//
 // PathDiagnosticBuilder and its associated routines and helper objects.
 //===----------------------------------------------------------------------===//
 
@@ -1749,6 +1794,11 @@
       GenerateMinimalPathDiagnostic(PD, PDB, N);
       break;
   }
+  
+  // Finally, prune the diagnostic path of uninteresting stuff.
+  bool hasSomethingInteresting = RemoveUneededCalls(PD.getMutablePieces());
+  assert(hasSomethingInteresting);
+  (void) hasSomethingInteresting;
 }
 
 void BugReporter::Register(BugType *BT) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=151663&r1=151662&r2=151663&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Tue Feb 28 17:06:21 2012
@@ -436,6 +436,17 @@
                                                    const ExplodedNode *Prev,
                                                    BugReporterContext &BRC,
                                                    BugReport &BR) {
+  PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
+  if (PathDiagnosticEventPiece *ev =
+      dyn_cast_or_null<PathDiagnosticEventPiece>(piece))
+    ev->setPrunable(true);
+  return piece;
+}
+
+PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
+                                                       const ExplodedNode *Prev,
+                                                       BugReporterContext &BRC,
+                                                       BugReport &BR) {
   
   const ProgramPoint &progPoint = N->getLocation();
 





More information about the cfe-commits mailing list