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