summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2016-10-07 19:25:10 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2016-10-07 19:25:10 +0000
commit6bc67a42a8bb22a8a75cc92c187219438504218e (patch)
treedb03f7f545cf5464b4bc1e844e16c6bdda0f15ec /lib
parent9ccc2ea6b64ec9a19102ba904a312e56faacb9d6 (diff)
downloadclang-6bc67a42a8bb22a8a75cc92c187219438504218e.tar.gz
[analyzer] Re-apply r283092, attempt no.4, chunk no.4 (last)
The problem that caused the msvc crash has been indentified and fixed in the previous commit. This patch contains the rest of r283092. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@283584 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp9
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp54
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp88
-rw-r--r--lib/StaticAnalyzer/Core/PlistDiagnostics.cpp3
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp24
6 files changed, 138 insertions, 47 deletions
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index 78aad3940d..27bb976a6e 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -324,6 +324,7 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter &R, FileID FID,
" .msgT { padding:0x; spacing:0x }\n"
" .msgEvent { background-color:#fff8b4; color:#000000 }\n"
" .msgControl { background-color:#bbbbbb; color:#000000 }\n"
+ " .msgNote { background-color:#ddeeff; color:#000000 }\n"
" .mrange { background-color:#dfddf3 }\n"
" .mrange { border-bottom:1px solid #6F9DBE }\n"
" .PathIndex { font-weight: bold; padding:0px 5px; "
@@ -343,8 +344,12 @@ void html::AddHeaderFooterInternalBuiltinCSS(Rewriter &R, FileID FID,
" border-collapse: collapse; border-spacing: 0px;\n"
" }\n"
" td.rowname {\n"
- " text-align:right; font-weight:bold; color:#444444;\n"
- " padding-right:2ex; }\n"
+ " text-align: right;\n"
+ " vertical-align: top;\n"
+ " font-weight: bold;\n"
+ " color:#444444;\n"
+ " padding-right:2ex;\n"
+ " }\n"
"</style>\n</head>\n<body>";
// Generate header
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index 54c668cd2d..86c194e8fa 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -344,3 +344,10 @@ bool AnalyzerOptions::shouldWidenLoops() {
WidenLoops = getBooleanOption("widen-loops", /*Default=*/false);
return WidenLoops.getValue();
}
+
+bool AnalyzerOptions::shouldDisplayNotesAsEvents() {
+ if (!DisplayNotesAsEvents.hasValue())
+ DisplayNotesAsEvents =
+ getBooleanOption("notes-as-events", /*Default=*/false);
+ return DisplayNotesAsEvents.getValue();
+}
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 578cbdc366..24dc887c1c 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -3410,25 +3410,28 @@ void BugReporter::FlushReport(BugReport *exampleReport,
exampleReport->getUniqueingLocation(),
exampleReport->getUniqueingDecl()));
- MaxBugClassSize = std::max(bugReports.size(),
- static_cast<size_t>(MaxBugClassSize));
-
- // Generate the full path diagnostic, using the generation scheme
- // specified by the PathDiagnosticConsumer. Note that we have to generate
- // path diagnostics even for consumers which do not support paths, because
- // the BugReporterVisitors may mark this bug as a false positive.
- if (!bugReports.empty())
+ if (exampleReport->isPathSensitive()) {
+ // Generate the full path diagnostic, using the generation scheme
+ // specified by the PathDiagnosticConsumer. Note that we have to generate
+ // path diagnostics even for consumers which do not support paths, because
+ // the BugReporterVisitors may mark this bug as a false positive.
+ assert(!bugReports.empty());
+
+ MaxBugClassSize =
+ std::max(bugReports.size(), static_cast<size_t>(MaxBugClassSize));
+
if (!generatePathDiagnostic(*D.get(), PD, bugReports))
return;
- MaxValidBugClassSize = std::max(bugReports.size(),
- static_cast<size_t>(MaxValidBugClassSize));
+ MaxValidBugClassSize =
+ std::max(bugReports.size(), static_cast<size_t>(MaxValidBugClassSize));
- // Examine the report and see if the last piece is in a header. Reset the
- // report location to the last piece in the main source file.
- AnalyzerOptions& Opts = getAnalyzerOptions();
- if (Opts.shouldReportIssuesInMainSourceFile() && !Opts.AnalyzeAll)
- D->resetDiagnosticLocationToMainFile();
+ // Examine the report and see if the last piece is in a header. Reset the
+ // report location to the last piece in the main source file.
+ AnalyzerOptions &Opts = getAnalyzerOptions();
+ if (Opts.shouldReportIssuesInMainSourceFile() && !Opts.AnalyzeAll)
+ D->resetDiagnosticLocationToMainFile();
+ }
// If the path is empty, generate a single step path with the location
// of the issue.
@@ -3441,6 +3444,27 @@ void BugReporter::FlushReport(BugReport *exampleReport,
D->setEndOfPath(std::move(piece));
}
+ PathPieces &Pieces = D->getMutablePieces();
+ if (getAnalyzerOptions().shouldDisplayNotesAsEvents()) {
+ // For path diagnostic consumers that don't support extra notes,
+ // we may optionally convert those to path notes.
+ for (auto I = exampleReport->getNotes().rbegin(),
+ E = exampleReport->getNotes().rend(); I != E; ++I) {
+ PathDiagnosticNotePiece *Piece = I->get();
+ PathDiagnosticEventPiece *ConvertedPiece =
+ new PathDiagnosticEventPiece(Piece->getLocation(),
+ Piece->getString());
+ for (const auto &R: Piece->getRanges())
+ ConvertedPiece->addRange(R);
+
+ Pieces.push_front(ConvertedPiece);
+ }
+ } else {
+ for (auto I = exampleReport->getNotes().rbegin(),
+ E = exampleReport->getNotes().rend(); I != E; ++I)
+ Pieces.push_front(*I);
+ }
+
// Get the meta data.
const BugReport::ExtraTextList &Meta = exampleReport->getExtraText();
for (BugReport::ExtraTextList::const_iterator i = Meta.begin(),
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index 3a18956e41..f157c3dd6c 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -152,13 +152,30 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
}
// Process the path.
- unsigned n = path.size();
- unsigned max = n;
-
- for (PathPieces::const_reverse_iterator I = path.rbegin(),
- E = path.rend();
- I != E; ++I, --n)
- HandlePiece(R, FID, **I, n, max);
+ // Maintain the counts of extra note pieces separately.
+ unsigned TotalPieces = path.size();
+ unsigned TotalNotePieces =
+ std::count_if(path.begin(), path.end(),
+ [](const IntrusiveRefCntPtr<PathDiagnosticPiece> &p) {
+ return isa<PathDiagnosticNotePiece>(p.get());
+ });
+
+ unsigned TotalRegularPieces = TotalPieces - TotalNotePieces;
+ unsigned NumRegularPieces = TotalRegularPieces;
+ unsigned NumNotePieces = TotalNotePieces;
+
+ for (auto I = path.rbegin(), E = path.rend(); I != E; ++I) {
+ if (isa<PathDiagnosticNotePiece>(I->get())) {
+ // This adds diagnostic bubbles, but not navigation.
+ // Navigation through note pieces would be added later,
+ // as a separate pass through the piece list.
+ HandlePiece(R, FID, **I, NumNotePieces, TotalNotePieces);
+ --NumNotePieces;
+ } else {
+ HandlePiece(R, FID, **I, NumRegularPieces, TotalRegularPieces);
+ --NumRegularPieces;
+ }
+ }
// Add line numbers, header, footer, etc.
@@ -192,24 +209,38 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
int ColumnNumber = path.back()->getLocation().asLocation().getExpansionColumnNumber();
// Add the name of the file as an <h1> tag.
-
{
std::string s;
llvm::raw_string_ostream os(s);
os << "<!-- REPORTHEADER -->\n"
- << "<h3>Bug Summary</h3>\n<table class=\"simpletable\">\n"
+ << "<h3>Bug Summary</h3>\n<table class=\"simpletable\">\n"
"<tr><td class=\"rowname\">File:</td><td>"
- << html::EscapeText(DirName)
- << html::EscapeText(Entry->getName())
- << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
- "<a href=\"#EndPath\">line "
- << LineNumber
- << ", column "
- << ColumnNumber
- << "</a></td></tr>\n"
- "<tr><td class=\"rowname\">Description:</td><td>"
- << D.getVerboseDescription() << "</td></tr>\n";
+ << html::EscapeText(DirName)
+ << html::EscapeText(Entry->getName())
+ << "</td></tr>\n<tr><td class=\"rowname\">Warning:</td><td>"
+ "<a href=\"#EndPath\">line "
+ << LineNumber
+ << ", column "
+ << ColumnNumber
+ << "</a><br />"
+ << D.getVerboseDescription() << "</td></tr>\n";
+
+ // The navigation across the extra notes pieces.
+ unsigned NumExtraPieces = 0;
+ for (const auto &Piece : path) {
+ if (const auto *P = dyn_cast<PathDiagnosticNotePiece>(Piece.get())) {
+ int LineNumber =
+ P->getLocation().asLocation().getExpansionLineNumber();
+ int ColumnNumber =
+ P->getLocation().asLocation().getExpansionColumnNumber();
+ os << "<tr><td class=\"rowname\">Note:</td><td>"
+ << "<a href=\"#Note" << NumExtraPieces << "\">line "
+ << LineNumber << ", column " << ColumnNumber << "</a><br />"
+ << P->getString() << "</td></tr>";
+ ++NumExtraPieces;
+ }
+ }
// Output any other meta data.
@@ -385,13 +416,20 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
// Create the html for the message.
const char *Kind = nullptr;
+ bool IsNote = false;
+ bool SuppressIndex = (max == 1);
switch (P.getKind()) {
case PathDiagnosticPiece::Call:
- llvm_unreachable("Calls should already be handled");
+ llvm_unreachable("Calls and extra notes should already be handled");
case PathDiagnosticPiece::Event: Kind = "Event"; break;
case PathDiagnosticPiece::ControlFlow: Kind = "Control"; break;
// Setting Kind to "Control" is intentional.
case PathDiagnosticPiece::Macro: Kind = "Control"; break;
+ case PathDiagnosticPiece::Note:
+ Kind = "Note";
+ IsNote = true;
+ SuppressIndex = true;
+ break;
}
std::string sbuf;
@@ -399,7 +437,9 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
os << "\n<tr><td class=\"num\"></td><td class=\"line\"><div id=\"";
- if (num == max)
+ if (IsNote)
+ os << "Note" << num;
+ else if (num == max)
os << "EndPath";
else
os << "Path" << num;
@@ -461,7 +501,7 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
os << "\">";
- if (max > 1) {
+ if (!SuppressIndex) {
os << "<table class=\"msgT\"><tr><td valign=\"top\">";
os << "<div class=\"PathIndex";
if (Kind) os << " PathIndex" << Kind;
@@ -501,7 +541,7 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
os << "':\n";
- if (max > 1) {
+ if (!SuppressIndex) {
os << "</td>";
if (num < max) {
os << "<td><div class=\"PathNav\"><a href=\"#";
@@ -523,7 +563,7 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
else {
os << html::EscapeText(P.getString());
- if (max > 1) {
+ if (!SuppressIndex) {
os << "</td>";
if (num < max) {
os << "<td><div class=\"PathNav\"><a href=\"#";
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index 206156ca22..c5263ee0e5 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -281,6 +281,9 @@ static void ReportPiece(raw_ostream &o,
ReportMacro(o, cast<PathDiagnosticMacroPiece>(P), FM, SM, LangOpts,
indent, depth);
break;
+ case PathDiagnosticPiece::Note:
+ // FIXME: Extend the plist format to support those.
+ break;
}
}
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 3b55a1d655..8bd0e125b8 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -113,16 +113,28 @@ public:
Diag.Report(WarnLoc, WarnID) << PD->getShortDescription()
<< PD->path.back()->getRanges();
+ // First, add extra notes, even if paths should not be included.
+ for (const auto &Piece : PD->path) {
+ if (!isa<PathDiagnosticNotePiece>(Piece.get()))
+ continue;
+
+ SourceLocation NoteLoc = Piece->getLocation().asLocation();
+ Diag.Report(NoteLoc, NoteID) << Piece->getString()
+ << Piece->getRanges();
+ }
+
if (!IncludePath)
continue;
+ // Then, add the path notes if necessary.
PathPieces FlatPath = PD->path.flatten(/*ShouldFlattenMacros=*/true);
- for (PathPieces::const_iterator PI = FlatPath.begin(),
- PE = FlatPath.end();
- PI != PE; ++PI) {
- SourceLocation NoteLoc = (*PI)->getLocation().asLocation();
- Diag.Report(NoteLoc, NoteID) << (*PI)->getString()
- << (*PI)->getRanges();
+ for (const auto &Piece : FlatPath) {
+ if (isa<PathDiagnosticNotePiece>(Piece.get()))
+ continue;
+
+ SourceLocation NoteLoc = Piece->getLocation().asLocation();
+ Diag.Report(NoteLoc, NoteID) << Piece->getString()
+ << Piece->getRanges();
}
}
}