ayartsev created this revision.
ayartsev added reviewers: zaks.anna, dcoughlin.
ayartsev added a subscriber: cfe-commits.

Hi all,

Currently if the path diagnostic consumer (e.g HTMLDiagnostics and 
PlistDiagnostics) do not support cross file diagnostics then the path 
diagnostic report is just silently omitted in the case of cross file 
diagnostics. If the analyzer finds an issue the missing report looks like a 
Clang bug as an issue is successfully reported to stdout but no report is 
generated.
The patch adds a little verbosity to Clang in the case considered above.
[[ https://llvm.org/bugs/show_bug.cgi?id=12421 | PR12421 ]] is devoted to the 
issue.
Please review!
Tried to write tests that would cover warnings inside the 'for' loop, but 
failed. Any ideas?

https://reviews.llvm.org/D22494

Files:
  lib/StaticAnalyzer/Core/PathDiagnostic.cpp
  test/Analysis/PR12421.c
  test/Analysis/PR12421.h

Index: test/Analysis/PR12421.h
===================================================================
--- test/Analysis/PR12421.h
+++ test/Analysis/PR12421.h
@@ -0,0 +1,4 @@
+static void f() {
+  int *p = 0;
+  *p = 1;       // expected-warning{{Dereference of null pointer}}
+}
Index: test/Analysis/PR12421.c
===================================================================
--- test/Analysis/PR12421.c
+++ test/Analysis/PR12421.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=html -o 
PR12421.html %s 2>&1 | FileCheck %s
+
+#include "PR12421.h"
+
+int main(){
+  f();
+  return 0;
+}
+
+// CHECK: warning: Path diagnostic report is not generated. HTMLDiagnostics 
does not support diagnostics that cross file boundaries.
Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp
===================================================================
--- lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -211,6 +211,10 @@
     const SourceManager &SMgr = D->path.front()->getLocation().getManager();
     SmallVector<const PathPieces *, 5> WorkList;
     WorkList.push_back(&D->path);
+    SmallString<128> buf;
+    llvm::raw_svector_ostream warning(buf);
+    warning << "warning: Path diagnostic report is not generated. " << 
getName()
+            << " does not support diagnostics that cross file boundaries.\n";
 
     while (!WorkList.empty()) {
       const PathPieces &path = *WorkList.pop_back_val();
@@ -222,19 +226,25 @@
 
         if (FID.isInvalid()) {
           FID = SMgr.getFileID(L);
-        } else if (SMgr.getFileID(L) != FID)
-          return; // FIXME: Emit a warning?
+        } else if (SMgr.getFileID(L) != FID) {
+          llvm::errs() << warning.str();
+          return;
+        }
 
         // Check the source ranges.
         ArrayRef<SourceRange> Ranges = piece->getRanges();
         for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
                                              E = Ranges.end(); I != E; ++I) {
           SourceLocation L = SMgr.getExpansionLoc(I->getBegin());
-          if (!L.isFileID() || SMgr.getFileID(L) != FID)
-            return; // FIXME: Emit a warning?
+          if (!L.isFileID() || SMgr.getFileID(L) != FID) {
+            llvm::errs() << warning.str();
+            return;
+          }
           L = SMgr.getExpansionLoc(I->getEnd());
-          if (!L.isFileID() || SMgr.getFileID(L) != FID)
-            return; // FIXME: Emit a warning?
+          if (!L.isFileID() || SMgr.getFileID(L) != FID) {
+            llvm::errs() << warning.str();
+            return;
+          }
         }
 
         if (const PathDiagnosticCallPiece *call =


Index: test/Analysis/PR12421.h
===================================================================
--- test/Analysis/PR12421.h
+++ test/Analysis/PR12421.h
@@ -0,0 +1,4 @@
+static void f() {
+  int *p = 0;
+  *p = 1;       // expected-warning{{Dereference of null pointer}}
+}
Index: test/Analysis/PR12421.c
===================================================================
--- test/Analysis/PR12421.c
+++ test/Analysis/PR12421.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=html -o PR12421.html %s 2>&1 | FileCheck %s
+
+#include "PR12421.h"
+
+int main(){
+  f();
+  return 0;
+}
+
+// CHECK: warning: Path diagnostic report is not generated. HTMLDiagnostics does not support diagnostics that cross file boundaries.
Index: lib/StaticAnalyzer/Core/PathDiagnostic.cpp
===================================================================
--- lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -211,6 +211,10 @@
     const SourceManager &SMgr = D->path.front()->getLocation().getManager();
     SmallVector<const PathPieces *, 5> WorkList;
     WorkList.push_back(&D->path);
+    SmallString<128> buf;
+    llvm::raw_svector_ostream warning(buf);
+    warning << "warning: Path diagnostic report is not generated. " << getName()
+            << " does not support diagnostics that cross file boundaries.\n";
 
     while (!WorkList.empty()) {
       const PathPieces &path = *WorkList.pop_back_val();
@@ -222,19 +226,25 @@
 
         if (FID.isInvalid()) {
           FID = SMgr.getFileID(L);
-        } else if (SMgr.getFileID(L) != FID)
-          return; // FIXME: Emit a warning?
+        } else if (SMgr.getFileID(L) != FID) {
+          llvm::errs() << warning.str();
+          return;
+        }
 
         // Check the source ranges.
         ArrayRef<SourceRange> Ranges = piece->getRanges();
         for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
                                              E = Ranges.end(); I != E; ++I) {
           SourceLocation L = SMgr.getExpansionLoc(I->getBegin());
-          if (!L.isFileID() || SMgr.getFileID(L) != FID)
-            return; // FIXME: Emit a warning?
+          if (!L.isFileID() || SMgr.getFileID(L) != FID) {
+            llvm::errs() << warning.str();
+            return;
+          }
           L = SMgr.getExpansionLoc(I->getEnd());
-          if (!L.isFileID() || SMgr.getFileID(L) != FID)
-            return; // FIXME: Emit a warning?
+          if (!L.isFileID() || SMgr.getFileID(L) != FID) {
+            llvm::errs() << warning.str();
+            return;
+          }
         }
 
         if (const PathDiagnosticCallPiece *call =
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to