r323251 - [analyzer] Mark lines as relevant even if they weren't executed but have a label attached

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 23 12:01:32 PST 2018


Author: george.karpenkov
Date: Tue Jan 23 12:01:31 2018
New Revision: 323251

URL: http://llvm.org/viewvc/llvm-project?rev=323251&view=rev
Log:
[analyzer] Mark lines as relevant even if they weren't executed but have a label attached

Differential Revision: https://reviews.llvm.org/D42320

Added:
    cfe/trunk/test/Analysis/html_diagnostics/relevant_lines/notexecutedlines.c
Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp?rev=323251&r1=323250&r2=323251&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp Tue Jan 23 12:01:31 2018
@@ -28,6 +28,8 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
+#include <map>
+#include <set>
 #include <sstream>
 
 using namespace clang;
@@ -96,11 +98,6 @@ public:
   std::string generateKeyboardNavigationJavascript();
 
 private:
-  /// \return JavaScript for an option to only show relevant lines.
-  std::string showRelevantLinesJavascript(const PathDiagnostic &D);
-
-  /// \return Executed lines from \p D in JSON format.
-  std::string serializeExecutedLines(const PathDiagnostic &D);
 
   /// \return Javascript for displaying shortcuts help;
   std::string showHelpJavascript();
@@ -333,6 +330,115 @@ std::string HTMLDiagnostics::GenerateHTM
   return os.str();
 }
 
+/// Write executed lines from \p D in JSON format into \p os.
+static void serializeExecutedLines(
+    const PathDiagnostic &D,
+    const PathPieces &path,
+    llvm::raw_string_ostream &os) {
+
+  // Copy executed lines from path diagnostics.
+  std::map<unsigned, std::set<unsigned>> ExecutedLines;
+  for (auto I = D.executedLines_begin(),
+            E = D.executedLines_end(); I != E; ++I) {
+    std::set<unsigned> &LinesInFile = ExecutedLines[I->first];
+    for (unsigned LineNo : I->second) {
+      LinesInFile.insert(LineNo);
+    }
+  }
+
+  // We need to include all lines for which any kind of diagnostics appears.
+  for (const auto &P : path) {
+    FullSourceLoc Loc = P->getLocation().asLocation().getExpansionLoc();
+    FileID FID = Loc.getFileID();
+    unsigned LineNo = Loc.getLineNumber();
+    ExecutedLines[FID.getHashValue()].insert(LineNo);
+  }
+
+  os << "var relevant_lines = {";
+  for (auto I = ExecutedLines.begin(),
+            E = ExecutedLines.end(); I != E; ++I) {
+    if (I != ExecutedLines.begin())
+      os << ", ";
+
+    os << "\"" << I->first << "\": {";
+    for (unsigned LineNo : I->second) {
+      if (LineNo != *(I->second.begin()))
+        os << ", ";
+
+      os << "\"" << LineNo << "\": 1";
+    }
+    os << "}";
+  }
+
+  os << "};";
+}
+
+/// \return JavaScript for an option to only show relevant lines.
+static std::string showRelevantLinesJavascript(
+      const PathDiagnostic &D, const PathPieces &path) {
+  std::string s;
+  llvm::raw_string_ostream os(s);
+  os << "<script type='text/javascript'>\n";
+  serializeExecutedLines(D, path, os);
+  os << R"<<<(
+
+var filterCounterexample = function (hide) {
+  var tables = document.getElementsByClassName("code");
+  for (var t=0; t<tables.length; t++) {
+    var table = tables[t];
+    var file_id = table.getAttribute("data-fileid");
+    var lines_in_fid = relevant_lines[file_id];
+    if (!lines_in_fid) {
+      lines_in_fid = {};
+    }
+    var lines = table.getElementsByClassName("codeline");
+    for (var i=0; i<lines.length; i++) {
+        var el = lines[i];
+        var lineNo = el.getAttribute("data-linenumber");
+        if (!lines_in_fid[lineNo]) {
+          if (hide) {
+            el.setAttribute("hidden", "");
+          } else {
+            el.removeAttribute("hidden");
+          }
+        }
+    }
+  }
+}
+
+window.addEventListener("keydown", function (event) {
+  if (event.defaultPrevented) {
+    return;
+  }
+  if (event.key == "S") {
+    var checked = document.getElementsByName("showCounterexample")[0].checked;
+    filterCounterexample(!checked);
+    document.getElementsByName("showCounterexample")[0].checked = !checked;
+  } else {
+    return;
+  }
+  event.preventDefault();
+}, true);
+
+document.addEventListener("DOMContentLoaded", function() {
+    document.querySelector('input[name="showCounterexample"]').onchange=
+        function (event) {
+      filterCounterexample(this.checked);
+    };
+});
+</script>
+
+<form>
+    <input type="checkbox" name="showCounterexample" id="showCounterexample" />
+    <label for="showCounterexample">
+       Show only relevant lines
+    </label>
+</form>
+)<<<";
+
+  return os.str();
+}
+
 void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter &R,
     const SourceManager& SMgr, const PathPieces& path, FileID FID,
     const FileEntry *Entry, const char *declName) {
@@ -357,7 +463,7 @@ void HTMLDiagnostics::FinalizeHTML(const
 
   // Checkbox and javascript for filtering the output to the counterexample.
   R.InsertTextBefore(SMgr.getLocForStartOfFile(FID),
-                     showRelevantLinesJavascript(D));
+                     showRelevantLinesJavascript(D, path));
 
   // Add the name of the file as an <h1> tag.
   {
@@ -507,93 +613,8 @@ window.addEventListener("keydown", funct
 )<<<";
 }
 
-std::string
-HTMLDiagnostics::showRelevantLinesJavascript(const PathDiagnostic &D) {
-  std::string s;
-  llvm::raw_string_ostream os(s);
-  os << "<script type='text/javascript'>\n";
-  os << serializeExecutedLines(D);
-  os << R"<<<(
 
-var filterCounterexample = function (hide) {
-  var tables = document.getElementsByClassName("code");
-  for (var t=0; t<tables.length; t++) {
-    var table = tables[t];
-    var file_id = table.getAttribute("data-fileid");
-    var lines_in_fid = relevant_lines[file_id];
-    if (!lines_in_fid) {
-      lines_in_fid = {};
-    }
-    var lines = table.getElementsByClassName("codeline");
-    for (var i=0; i<lines.length; i++) {
-        var el = lines[i];
-        var lineNo = el.getAttribute("data-linenumber");
-        if (!lines_in_fid[lineNo]) {
-          if (hide) {
-            el.setAttribute("hidden", "");
-          } else {
-            el.removeAttribute("hidden");
-          }
-        }
-    }
-  }
-}
 
-window.addEventListener("keydown", function (event) {
-  if (event.defaultPrevented) {
-    return;
-  }
-  if (event.key == "S") {
-    var checked = document.getElementsByName("showCounterexample")[0].checked;
-    filterCounterexample(!checked);
-    document.getElementsByName("showCounterexample")[0].checked = !checked;
-  } else {
-    return;
-  } 
-  event.preventDefault();
-}, true);
-
-document.addEventListener("DOMContentLoaded", function() {
-    document.querySelector('input[name="showCounterexample"]').onchange=
-        function (event) {
-      filterCounterexample(this.checked);
-    };
-});
-</script>
-
-<form>
-    <input type="checkbox" name="showCounterexample" />
-    <label for="showCounterexample">
-       Show only relevant lines
-    </label>
-</form>
-)<<<";
-
-  return os.str();
-}
-
-std::string HTMLDiagnostics::serializeExecutedLines(const PathDiagnostic &D) {
-  std::string s;
-  llvm::raw_string_ostream os(s);
-  os << "var relevant_lines = {";
-  for (auto I = D.executedLines_begin(),
-            E = D.executedLines_end(); I != E; ++I) {
-    if (I != D.executedLines_begin())
-      os << ", ";
-
-    os << "\"" << I->first << "\": {";
-    for (unsigned LineNo : I->second) {
-      if (LineNo != *(I->second.begin()))
-        os << ", ";
-
-      os << "\"" << LineNo << "\": 1";
-    }
-    os << "}";
-  }
-
-  os << "};";
-  return os.str();
-}
 
 void HTMLDiagnostics::RewriteFile(Rewriter &R, const SourceManager& SMgr,
     const PathPieces& path, FileID FID) {
@@ -1007,7 +1028,7 @@ window.addEventListener("keydown", funct
     navigateTo(/*up=*/true);
   } else {
     return;
-  } 
+  }
   event.preventDefault();
 }, true);
 </script>

Added: cfe/trunk/test/Analysis/html_diagnostics/relevant_lines/notexecutedlines.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/html_diagnostics/relevant_lines/notexecutedlines.c?rev=323251&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/html_diagnostics/relevant_lines/notexecutedlines.c (added)
+++ cfe/trunk/test/Analysis/html_diagnostics/relevant_lines/notexecutedlines.c Tue Jan 23 12:01:31 2018
@@ -0,0 +1,12 @@
+int f() {
+  int zzz = 200;
+  zzz += 100;
+  return 0;
+}
+
+// Show line with the warning even if it wasn't executed (e.g. warning given
+// by path-insensitive analysis).
+// RUN: rm -rf %t.output
+// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core,deadcode -analyzer-output html -o %t.output %s
+// RUN: cat %t.output/* | FileCheck %s --match-full-lines
+// CHECK: var relevant_lines = {"1": {"3": 1}};




More information about the cfe-commits mailing list