[analyzer] Move report false positive suppression to report visitors.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173956 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 74579b7..7a87e47 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -457,11 +457,6 @@
void Register(BugType *BT);
- /// \brief Suppress reports that might lead to known false positives.
- ///
- /// Currently this suppresses reports based on locations of bugs.
- bool suppressReport(BugReport *R);
-
/// \brief Add the given report to the set of reports tracked by BugReporter.
///
/// The reports are usually generated by the checkers. Further, they are
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index 86f9af3..10fd445 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -230,6 +230,33 @@
llvm::Optional<bool> &prunable);
};
+/// \brief Suppress reports that might lead to known false positives.
+///
+/// Currently this suppresses reports based on locations of bugs.
+class LikelyFalsePositiveSuppressionBRVisitor
+ : public BugReporterVisitorImpl<LikelyFalsePositiveSuppressionBRVisitor> {
+public:
+ static void *getTag() {
+ static int Tag = 0;
+ return static_cast<void *>(&Tag);
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddPointer(getTag());
+ }
+
+ virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+ const ExplodedNode *Prev,
+ BugReporterContext &BRC,
+ BugReport &BR) {
+ return 0;
+ }
+
+ virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
+ const ExplodedNode *N,
+ BugReport &BR);
+};
+
/// \brief When a region containing undefined value or '0' value is passed
/// as an argument in a call, marks the call as interesting.
///
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 4734728..fccebf4 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -2047,6 +2047,7 @@
// Register additional node visitors.
R->addVisitor(new NilReceiverBRVisitor());
R->addVisitor(new ConditionBRVisitor());
+ R->addVisitor(new LikelyFalsePositiveSuppressionBRVisitor());
BugReport::VisitorList visitors;
unsigned originalReportConfigToken, finalReportConfigToken;
@@ -2067,16 +2068,17 @@
// Generate the very last diagnostic piece - the piece is visible before
// the trace is expanded.
- if (PDB.getGenerationScheme() != PathDiagnosticConsumer::None) {
- PathDiagnosticPiece *LastPiece = 0;
- for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end();
- I != E; ++I) {
- if (PathDiagnosticPiece *Piece = (*I)->getEndPath(PDB, N, *R)) {
- assert (!LastPiece &&
- "There can only be one final piece in a diagnostic.");
- LastPiece = Piece;
- }
+ PathDiagnosticPiece *LastPiece = 0;
+ for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end();
+ I != E; ++I) {
+ if (PathDiagnosticPiece *Piece = (*I)->getEndPath(PDB, N, *R)) {
+ assert (!LastPiece &&
+ "There can only be one final piece in a diagnostic.");
+ LastPiece = Piece;
}
+ }
+
+ if (PDB.getGenerationScheme() != PathDiagnosticConsumer::None) {
if (!LastPiece)
LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
if (LastPiece)
@@ -2141,32 +2143,7 @@
BugTypes = F.add(BugTypes, BT);
}
-bool BugReporter::suppressReport(BugReport *R) {
- const Stmt *S = R->getStmt();
- if (!S)
- return false;
-
- // Here we suppress false positives coming from system macros. This list is
- // based on known issues.
-
- // Skip reports within the sys/queue.h macros as we do not have the ability to
- // reason about data structure shapes.
- SourceManager &SM = getSourceManager();
- SourceLocation Loc = S->getLocStart();
- while (Loc.isMacroID()) {
- if (SM.isInSystemMacro(Loc) &&
- (SM.getFilename(SM.getSpellingLoc(Loc)).endswith("sys/queue.h")))
- return true;
- Loc = SM.getSpellingLoc(Loc);
- }
-
- return false;
-}
-
void BugReporter::emitReport(BugReport* R) {
- if (suppressReport(R))
- return;
-
// Compute the bug report's hash to determine its equivalence class.
llvm::FoldingSetNodeID ID;
R->Profile(ID);
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 7cd1319..3aa3515 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -1157,6 +1157,33 @@
}
PathDiagnosticPiece *
+LikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC,
+ const ExplodedNode *N,
+ BugReport &BR) {
+ const Stmt *S = BR.getStmt();
+ if (!S)
+ return 0;
+
+ // Here we suppress false positives coming from system macros. This list is
+ // based on known issues.
+
+ // Skip reports within the sys/queue.h macros as we do not have the ability to
+ // reason about data structure shapes.
+ SourceManager &SM = BRC.getSourceManager();
+ SourceLocation Loc = S->getLocStart();
+ while (Loc.isMacroID()) {
+ if (SM.isInSystemMacro(Loc) &&
+ (SM.getFilename(SM.getSpellingLoc(Loc)).endswith("sys/queue.h"))) {
+ BR.markInvalid(getTag(), 0);
+ return 0;
+ }
+ Loc = SM.getSpellingLoc(Loc);
+ }
+
+ return 0;
+}
+
+PathDiagnosticPiece *
UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,
BugReporterContext &BRC,