]> granicus.if.org Git - clang/commitdiff
[analyzer diagnostics] Refactor filtration for PathDiagnosticConsumers that don't...
authorTed Kremenek <kremenek@apple.com>
Tue, 28 Feb 2012 23:27:39 +0000 (23:27 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 28 Feb 2012 23:27:39 +0000 (23:27 +0000)
into a common place.  Currently enable this filtration for Plist diagnostics as well.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151664 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
lib/StaticAnalyzer/Core/PathDiagnostic.cpp

index 42d8482ebaefd6b36dc09ea54ceea3a25eb17198..965ac3085e632f46650456f00283e53ffe5c9da6 100644 (file)
@@ -68,6 +68,10 @@ public:
   virtual bool supportsLogicalOpControlFlow() const { return false; }
   virtual bool supportsAllBlockEdges() const { return false; }
   virtual bool useVerboseDescription() const { return true; }
+  
+  /// Return true if the PathDiagnosticConsumer supports individual
+  /// PathDiagnostics that span multiple files.
+  virtual bool supportsCrossFileDiagnostics() const { return false; }
 
 protected:
   bool flushed;
index 8004ef45a6645a19d27cefd922efb796b663ed36..3740ba1005b70a25687b469c03dca34a32926a8d 100644 (file)
@@ -145,35 +145,14 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
   // First flatten out the entire path to make it easier to use.
   PathPieces path;
   flattenPath(path, D.path);
-  
-  const SourceManager &SMgr = (*path.begin())->getLocation().getManager();
-  FileID FID;
-
-  // Verify that the entire path is from the same FileID.
-  for (PathPieces::const_iterator I = path.begin(), E = path.end();
-       I != E; ++I) {
-    FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc();
-
-    if (FID.isInvalid()) {
-      FID = SMgr.getFileID(L);
-    } else if (SMgr.getFileID(L) != FID)
-      return; // FIXME: Emit a warning?
-
-    // Check the source ranges.
-    for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
-                                             RE = (*I)->ranges_end();
-                                             RI != RE; ++RI) {
-      SourceLocation L = SMgr.getExpansionLoc(RI->getBegin());
-      if (!L.isFileID() || SMgr.getFileID(L) != FID)
-        return; // FIXME: Emit a warning?
-      L = SMgr.getExpansionLoc(RI->getEnd());
-      if (!L.isFileID() || SMgr.getFileID(L) != FID)
-        return; // FIXME: Emit a warning?
-    }
-  }
 
-  if (FID.isInvalid())
-    return; // FIXME: Emit a warning?
+  // The path as already been prechecked that all parts of the path are
+  // from the same file and that it is non-empty.
+  const SourceManager &SMgr = (*path.begin())->getLocation().getManager();
+  assert(!path.empty());
+  FileID FID =
+    (*path.begin())->getLocation().asLocation().getExpansionLoc().getFileID();
+  assert(!FID.isInvalid());
 
   // Create a new rewriter to generate HTML.
   Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
index a866b34158e87c9e3259bae258fc3b2235bfe94b..2adc0f2c38b6017dc397eea81d700eeebdd608dd 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
@@ -76,19 +77,49 @@ PathDiagnosticConsumer::~PathDiagnosticConsumer() {
 }
 
 void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) {
-  if (!D)
-    return;
+  llvm::OwningPtr<PathDiagnostic> OwningD(D);
   
-  if (D->path.empty()) {
-    delete D;
+  if (!D || D->path.empty())
     return;
-  }
   
   // We need to flatten the locations (convert Stmt* to locations) because
   // the referenced statements may be freed by the time the diagnostics
   // are emitted.
   D->flattenLocations();
 
+  // If the PathDiagnosticConsumer does not support diagnostics that
+  // cross file boundaries, prune out such diagnostics now.
+  if (!supportsCrossFileDiagnostics()) {
+    // Verify that the entire path is from the same FileID.
+    FileID FID;
+    const SourceManager &SMgr = (*D->path.begin())->getLocation().getManager();
+
+    for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
+         I != E; ++I) {
+      FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc();
+      
+      if (FID.isInvalid()) {
+        FID = SMgr.getFileID(L);
+      } else if (SMgr.getFileID(L) != FID)
+        return; // FIXME: Emit a warning?
+      
+      // Check the source ranges.
+      for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
+           RE = (*I)->ranges_end();
+           RI != RE; ++RI) {
+        SourceLocation L = SMgr.getExpansionLoc(RI->getBegin());
+        if (!L.isFileID() || SMgr.getFileID(L) != FID)
+          return; // FIXME: Emit a warning?
+        L = SMgr.getExpansionLoc(RI->getEnd());
+        if (!L.isFileID() || SMgr.getFileID(L) != FID)
+          return; // FIXME: Emit a warning?
+      }
+    }
+    
+    if (FID.isInvalid())
+      return; // FIXME: Emit a warning?
+  }  
+
   // Profile the node to see if we already have something matching it
   llvm::FoldingSetNodeID profile;
   D->Profile(profile);
@@ -110,16 +141,14 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) {
           shouldKeepOriginal = false;
       }
 
-      if (shouldKeepOriginal) {
-        delete D;
+      if (shouldKeepOriginal)
         return;
-      }
     }
     Diags.RemoveNode(orig);
     delete orig;
   }
   
-  Diags.InsertNode(D);
+  Diags.InsertNode(OwningD.take());
 }