]> granicus.if.org Git - clang/commitdiff
[analyzer] Move report false positive suppression to report visitors.
authorAnna Zaks <ganna@apple.com>
Wed, 30 Jan 2013 19:12:34 +0000 (19:12 +0000)
committerAnna Zaks <ganna@apple.com>
Wed, 30 Jan 2013 19:12:34 +0000 (19:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173956 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
lib/StaticAnalyzer/Core/BugReporter.cpp
lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

index 74579b7b4cb463f7a298de19baca3315323f5132..7a87e47f74ce2bbdebf6c70ce44b820f57c524e2 100644 (file)
@@ -457,11 +457,6 @@ public:
 
   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
index 86f9af352cb8dc7f2cd32877a8ea8bb3a19f2dc9..10fd445b8c01abbea72f5cb523319b64740465c8 100644 (file)
@@ -230,6 +230,33 @@ public:
                     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.
 ///
index 473472872b18579105a3fac079a72119d92f5947..fccebf4c7912c6e69087c2f1201134feba8b0a69 100644 (file)
@@ -2047,6 +2047,7 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
   // 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 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
 
     // 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 @@ void BugReporter::Register(BugType *BT) {
   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);
index 7cd1319af29cd092e641cdca9313bf76efd21e5c..3aa351527f3ba2ae76d3ebbf14ffc133f3022efc 100644 (file)
@@ -1156,6 +1156,33 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
   return event;
 }
 
+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,