summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2016-10-03 07:58:26 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2016-10-03 07:58:26 +0000
commit9dceb11b2fd4c5e34b759d26ce3a63dbe3a80a77 (patch)
tree3960f3f364e51d246ff2be9f9116a7f595713465 /clang/lib/StaticAnalyzer/Core/BugReporter.cpp
parentfe91cf3abaf97464f0c180e0809fdbe3b5c6285e (diff)
downloadbcm5719-llvm-9dceb11b2fd4c5e34b759d26ce3a63dbe3a80a77.tar.gz
bcm5719-llvm-9dceb11b2fd4c5e34b759d26ce3a63dbe3a80a77.zip
[analyzer] Extend bug reports with extra notes
These diagnostics are separate from the path-sensitive engine's path notes, and can be added manually on top of path-sensitive or path-insensitive reports. The new note diagnostics would appear as note:-diagnostic on console and as blue bubbles in scan-build. In plist files they currently do not appear, because format needs to be discussed with plist file users. The analyzer option "-analyzer-config notes-as-events=true" would convert notes to normal path notes, and put them at the beginning of the path. This is a temporary hack to show the new notes in plist files. A few checkers would be updated in subsequent commits, including tests for this new feature. Differential Revision: https://reviews.llvm.org/D24278 llvm-svn: 283092
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/BugReporter.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/BugReporter.cpp72
1 files changed, 54 insertions, 18 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
index e04aa395d49..0ea5d0cf298 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -112,15 +112,15 @@ static void removeRedundantMsgs(PathPieces &path) {
path.pop_front();
switch (piece->getKind()) {
- case clang::ento::PathDiagnosticPiece::Call:
+ case PathDiagnosticPiece::Call:
removeRedundantMsgs(cast<PathDiagnosticCallPiece>(piece)->path);
break;
- case clang::ento::PathDiagnosticPiece::Macro:
+ case PathDiagnosticPiece::Macro:
removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(piece)->subPieces);
break;
- case clang::ento::PathDiagnosticPiece::ControlFlow:
+ case PathDiagnosticPiece::ControlFlow:
break;
- case clang::ento::PathDiagnosticPiece::Event: {
+ case PathDiagnosticPiece::Event: {
if (i == N-1)
break;
@@ -140,6 +140,8 @@ static void removeRedundantMsgs(PathPieces &path) {
}
break;
}
+ case PathDiagnosticPiece::Note:
+ break;
}
path.push_back(piece);
}
@@ -197,6 +199,9 @@ static bool removeUnneededCalls(PathPieces &pieces, BugReport *R,
}
case PathDiagnosticPiece::ControlFlow:
break;
+
+ case PathDiagnosticPiece::Note:
+ break;
}
pieces.push_back(piece);
@@ -3403,25 +3408,28 @@ void BugReporter::FlushReport(BugReport *exampleReport,
exampleReport->getUniqueingLocation(),
exampleReport->getUniqueingDecl()));
- MaxBugClassSize = std::max(bugReports.size(),
- static_cast<size_t>(MaxBugClassSize));
+ 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));
- // 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 (!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.
@@ -3434,6 +3442,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(),
@@ -3518,6 +3547,13 @@ LLVM_DUMP_METHOD void PathDiagnosticMacroPiece::dump() const {
// FIXME: Print which macro is being invoked.
}
+LLVM_DUMP_METHOD void PathDiagnosticNotePiece::dump() const {
+ llvm::errs() << "NOTE\n--------------\n";
+ llvm::errs() << getString() << "\n";
+ llvm::errs() << " ---- at ----\n";
+ getLocation().dump();
+}
+
LLVM_DUMP_METHOD void PathDiagnosticLocation::dump() const {
if (!isValid()) {
llvm::errs() << "<INVALID>\n";
OpenPOWER on IntegriCloud