From: George Karpenkov Date: Tue, 23 Jan 2018 20:01:31 +0000 (+0000) Subject: [analyzer] Mark lines as relevant even if they weren't executed but have a label... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=21dbb8daf23ab221641b8f8ac4a883158a46f1b1;p=clang [analyzer] Mark lines as relevant even if they weren't executed but have a label attached Differential Revision: https://reviews.llvm.org/D42320 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@323251 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index 12f6b13013..c6e397fa6a 100644 --- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -28,6 +28,8 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include +#include #include 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::GenerateHTML(const PathDiagnostic& D, Rewriter &R, 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> ExecutedLines; + for (auto I = D.executedLines_begin(), + E = D.executedLines_end(); I != E; ++I) { + std::set &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 << " + +
+ + +
+)<<<"; + + 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 PathDiagnostic& D, Rewriter &R, // 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

tag. { @@ -507,93 +613,8 @@ window.addEventListener("keydown", function (event) { )<<<"; } -std::string -HTMLDiagnostics::showRelevantLinesJavascript(const PathDiagnostic &D) { - std::string s; - llvm::raw_string_ostream os(s); - os << " - -
- - -
-)<<<"; - - 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", function (event) { navigateTo(/*up=*/true); } else { return; - } + } event.preventDefault(); }, true); diff --git a/test/Analysis/html_diagnostics/relevant_lines/notexecutedlines.c b/test/Analysis/html_diagnostics/relevant_lines/notexecutedlines.c new file mode 100644 index 0000000000..3c723aa933 --- /dev/null +++ b/test/Analysis/html_diagnostics/relevant_lines/notexecutedlines.c @@ -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}};