Charusso updated this revision to Diff 214500.
Charusso added a comment.

- Fix a comment.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66042/new/

https://reviews.llvm.org/D66042

Files:
  clang-tools-extra/clang-tidy/ClangTidy.cpp
  clang/include/clang/Driver/CC1Options.td
  clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/StaticAnalyzer/Core/BugReporter.cpp
  clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
  clang/test/Analysis/silence-checker-core-all.cpp
  clang/test/Analysis/silence-checker-core-div-by-zero.cpp
  clang/tools/scan-build/bin/scan-build
  clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp

Index: clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
===================================================================
--- clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
+++ clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
@@ -46,7 +46,7 @@
     std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer =
         CreateAnalysisConsumer(Compiler);
     AnalysisConsumer->AddDiagnosticConsumer(new DiagConsumer(DiagsOutput));
-    Compiler.getAnalyzerOpts()->CheckersControlList = {
+    Compiler.getAnalyzerOpts()->CheckerAnalysisVector = {
         {"custom.CustomChecker", true}};
     AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
       Registry.addChecker<CheckerT>("custom.CustomChecker", "Description", "");
Index: clang/tools/scan-build/bin/scan-build
===================================================================
--- clang/tools/scan-build/bin/scan-build
+++ clang/tools/scan-build/bin/scan-build
@@ -57,6 +57,7 @@
   KeepEmpty => 0,            # Don't remove output directory even with 0 results.
   EnableCheckers => {},
   DisableCheckers => {},
+  SilenceCheckers => {},
   Excludes => [],
   UseCC => undef,            # C compiler to use for compilation.
   UseCXX => undef,           # C++ compiler to use for compilation.
@@ -1742,9 +1743,15 @@
     if ($arg eq "-disable-checker") {
       shift @$Args;
       my $Checker = shift @$Args;
-      # Store $NumArgs to preserve the order the checkers were disabled.
-      $Options{DisableCheckers}{$Checker} = $NumArgs;
-      delete $Options{EnableCheckers}{$Checker};
+      # Store $NumArgs to preserve the order the checkers/warnings are disabled.
+      # See whether it is a core checker to disable. That means we do not want
+      # to emit a report from that checker so we have to silence it.
+      if (index($Checker, "core") == 0) {
+        $Options{SilenceCheckers}{$Checker} = $NumArgs;
+      } else {
+        $Options{DisableCheckers}{$Checker} = $NumArgs;
+        delete $Options{EnableCheckers}{$Checker};
+      }
       next;
     }
 
@@ -1882,6 +1889,11 @@
   # Push checkers in order they were disabled.
   push @AnalysesToRun, "-analyzer-disable-checker", $_;
 }
+foreach (sort { $Options{SilenceCheckers}{$a} <=> $Options{SilenceCheckers}{$b} }
+         keys %{$Options{SilenceCheckersl}}) {
+  # Push checkers in order they were silenced.
+  push @AnalysesToRun, "-analyzer-silence-checker", $_;
+}
 if ($Options{AnalyzeHeaders}) { push @AnalysesToRun, "-analyzer-opt-analyze-headers"; }
 if ($Options{AnalyzerStats}) { push @AnalysesToRun, '-analyzer-checker=debug.Stats'; }
 if ($Options{MaxLoop} > 0) { push @AnalysesToRun, "-analyzer-max-loop $Options{MaxLoop}"; }
Index: clang/test/Analysis/silence-checker-core-div-by-zero.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/silence-checker-core-div-by-zero.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=core \
+// RUN:  -analyzer-silence-checker core.DivideZero \
+// RUN:  -verify %s
+
+void test_disable_core_div_by_zero() {
+  (void)(1 / 0);
+  // expected-warning@-1 {{division by zero is undefined}}
+  // no-warning: 'Division by zero'
+}
Index: clang/test/Analysis/silence-checker-core-all.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/silence-checker-core-all.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=core \
+// RUN:  -analyzer-silence-checker=core \
+// RUN:  -verify %s
+
+// expected-no-diagnostics
+
+void test_disable_core_all(int *p) {
+  if (p)
+    return;
+
+  int x = p[0];
+  // no-warning: Array access (from variable 'p') results in a null pointer dereference
+}
Index: clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
+++ clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
@@ -200,7 +200,7 @@
 
   // Parse '-analyzer-checker' and '-analyzer-disable-checker' options from the
   // command line.
-  for (const std::pair<std::string, bool> &Opt : AnOpts.CheckersControlList) {
+  for (const std::pair<std::string, bool> &Opt : AnOpts.CheckerAnalysisVector) {
     CheckerInfoListRange CheckerForCmdLineArg =
         getMutableCheckersForCmdLineArg(Opt.first);
 
Index: clang/lib/StaticAnalyzer/Core/BugReporter.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ clang/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -1917,12 +1917,19 @@
     PathDiagnosticBuilder &PDB,
     const ExplodedNode *ErrorNode,
     const VisitorsDiagnosticsTy &VisitorsDiagnostics) {
+  BugReport *R = PDB.getBugReport();
+  AnalyzerOptions &Opts = PDB.getBugReporter().getAnalyzerOptions();
+  StringRef ErrorTag = ErrorNode->getLocation().getTag()->getTagDescription();
+
+  // See whether we need to silence the checker.
+  for (const std::string &CheckerName : Opts.CheckerSilenceVector) {
+    if (ErrorTag.startswith(CheckerName))
+      return nullptr;
+  }
 
   bool GenerateDiagnostics = (ActiveScheme != PathDiagnosticConsumer::None);
   bool AddPathEdges = (ActiveScheme == PathDiagnosticConsumer::Extensive);
   SourceManager &SM = PDB.getSourceManager();
-  BugReport *R = PDB.getBugReport();
-  AnalyzerOptions &Opts = PDB.getBugReporter().getAnalyzerOptions();
   StackDiagVector CallStack;
   InterestingExprs IE;
   LocationContextMap LCM;
@@ -2686,9 +2693,12 @@
     const ExplodedNode *ErrorNode = ErrorGraph.ErrorNode;
     for (PathDiagnosticConsumer *PC : consumers) {
       PathDiagnosticBuilder PDB(*this, R, ErrorGraph.BackMap, PC);
-      std::unique_ptr<PathDiagnostic> PD = generatePathDiagnosticForConsumer(
-          PC->getGenerationScheme(), PDB, ErrorNode, *ReportInfo.second);
-      (*Out)[PC] = std::move(PD);
+      if (std::unique_ptr<PathDiagnostic> PD =
+              generatePathDiagnosticForConsumer(PC->getGenerationScheme(), PDB,
+                                                ErrorNode,
+                                                *ReportInfo.second)) {
+        (*Out)[PC] = std::move(PD);
+      }
     }
   }
 
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -324,7 +324,7 @@
       getLastArgIntValue(Args, OPT_analyzer_inline_max_stack_depth,
                          Opts.InlineMaxStackDepth, Diags);
 
-  Opts.CheckersControlList.clear();
+  Opts.CheckerAnalysisVector.clear();
   for (const Arg *A :
        Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) {
     A->claim();
@@ -332,10 +332,22 @@
     // We can have a list of comma separated checker names, e.g:
     // '-analyzer-checker=cocoa,unix'
     StringRef checkerList = A->getValue();
-    SmallVector<StringRef, 4> checkers;
+    SmallVector<StringRef, 16> checkers;
     checkerList.split(checkers, ",");
     for (auto checker : checkers)
-      Opts.CheckersControlList.emplace_back(checker, enable);
+      Opts.CheckerAnalysisVector.emplace_back(checker, enable);
+  }
+
+  Opts.CheckerSilenceVector.clear();
+  for (const Arg *A : Args.filtered(OPT_analyzer_silence_checker)) {
+    A->claim();
+    // We can have a list of comma separated checker names, e.g:
+    // '-analyzer-checker=cocoa,unix'
+    StringRef checkerList = A->getValue();
+    SmallVector<StringRef, 16> checkers;
+    checkerList.split(checkers, ",");
+    for (auto checker : checkers)
+      Opts.CheckerSilenceVector.emplace_back(checker);
   }
 
   // Go through the analyzer configuration options.
Index: clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -189,8 +189,11 @@
       size_t EntryWidth, size_t InitialPad, size_t MinLineWidth = 0);
 
 
-  /// Pair of checker name and enable/disable.
-  std::vector<std::pair<std::string, bool>> CheckersControlList;
+  /// Pair of checker name and enable/disable to do analysis.
+  std::vector<std::pair<std::string, bool>> CheckerAnalysisVector;
+
+  /// Vector of checker names to do not emit warnings.
+  std::vector<std::string> CheckerSilenceVector;
 
   /// A key-value table of use-specified configuration values.
   // TODO: This shouldn't be public.
Index: clang/include/clang/Driver/CC1Options.td
===================================================================
--- clang/include/clang/Driver/CC1Options.td
+++ clang/include/clang/Driver/CC1Options.td
@@ -124,6 +124,11 @@
 def analyzer_disable_checker_EQ : Joined<["-"], "analyzer-disable-checker=">,
   Alias<analyzer_disable_checker>;
 
+def analyzer_silence_checker : Separate<["-"], "analyzer-silence-checker">,
+  HelpText<"Choose analyzer checkers to silence">;
+def analyzer_silence_checker_EQ : Joined<["-"], "analyzer-silence-checker=">,
+  Alias<analyzer_silence_checker>;
+
 def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">,
   HelpText<"Disable all static analyzer checks">;
 
Index: clang-tools-extra/clang-tidy/ClangTidy.cpp
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ clang-tools-extra/clang-tidy/ClangTidy.cpp
@@ -419,9 +419,9 @@
 
 #if CLANG_ENABLE_STATIC_ANALYZER
   AnalyzerOptionsRef AnalyzerOptions = Compiler.getAnalyzerOpts();
-  AnalyzerOptions->CheckersControlList =
+  AnalyzerOptions->CheckerAnalysisVector =
       getCheckersControlList(Context, Context.canEnableAnalyzerAlphaCheckers());
-  if (!AnalyzerOptions->CheckersControlList.empty()) {
+  if (!AnalyzerOptions->CheckerAnalysisVector.empty()) {
     setStaticAnalyzerCheckerOpts(Context.getOptions(), AnalyzerOptions);
     AnalyzerOptions->AnalysisStoreOpt = RegionStoreModel;
     AnalyzerOptions->AnalysisDiagOpt = PD_NONE;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to