r369078 - [analyzer] Analysis: Silence checkers

Csaba Dabis via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 15 18:53:14 PDT 2019


Author: charusso
Date: Thu Aug 15 18:53:14 2019
New Revision: 369078

URL: http://llvm.org/viewvc/llvm-project?rev=369078&view=rev
Log:
[analyzer] Analysis: Silence checkers

Summary:
This patch introduces a new `analyzer-config` configuration:
`-analyzer-config silence-checkers`
which could be used to silence the given checkers.

It accepts a semicolon separated list, packed into quotation marks, e.g:
`-analyzer-config silence-checkers="core.DivideZero;core.NullDereference"`

It could be used to "disable" core checkers, so they model the analysis as
before, just if some of them are too noisy it prevents to emit reports.

This patch also adds support for that new option to the scan-build.
Passing the option `-disable-checker core.DivideZero` to the scan-build
will be transferred to `-analyzer-config silence-checkers=core.DivideZero`.

Reviewed By: NoQ, Szelethus

Differential Revision: https://reviews.llvm.org/D66042

Added:
    cfe/trunk/test/Analysis/silence-checkers-and-packages-core-all.cpp
    cfe/trunk/test/Analysis/silence-checkers-and-packages-core-div-by-zero.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
    cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
    cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
    cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
    cfe/trunk/test/Analysis/analyzer-config.c
    cfe/trunk/tools/scan-build/bin/scan-build
    cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Thu Aug 15 18:53:14 2019
@@ -300,7 +300,7 @@ def err_omp_more_one_clause : Error<
   "directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">;
 
 // Static Analyzer Core
-def err_unknown_analyzer_checker : Error<
+def err_unknown_analyzer_checker_or_package : Error<
     "no analyzer checkers or packages are associated with '%0'">;
 def note_suggest_disabling_all_checkers : Note<
     "use -analyzer-disable-all-checks to disable all static analyzer checkers">;

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def Thu Aug 15 18:53:14 2019
@@ -380,12 +380,6 @@ ANALYZER_OPTION(
     "Value: \"constructors\", \"destructors\", \"methods\".",
     "destructors")
 
-ANALYZER_OPTION_DEPENDS_ON_USER_MODE(
-    StringRef, IPAMode, "ipa",
-    "Controls the mode of inter-procedural analysis. Value: \"none\", "
-    "\"basic-inlining\", \"inlining\", \"dynamic\", \"dynamic-bifurcate\".",
-    /* SHALLOW_VAL */ "inlining", /* DEEP_VAL */ "dynamic-bifurcate")
-
 ANALYZER_OPTION(
     StringRef, ExplorationStrategy, "exploration_strategy",
     "Value: \"dfs\", \"bfs\", \"unexplored_first\", "
@@ -393,5 +387,17 @@ ANALYZER_OPTION(
     "\"bfs_block_dfs_contents\".",
     "unexplored_first_queue")
 
+ANALYZER_OPTION(
+    StringRef, RawSilencedCheckersAndPackages, "silence-checkers",
+    "A semicolon separated list of checker and package names to silence. "
+    "Silenced checkers will not emit reports, but the modeling remain enabled.",
+    "")
+
+ANALYZER_OPTION_DEPENDS_ON_USER_MODE(
+    StringRef, IPAMode, "ipa",
+    "Controls the mode of inter-procedural analysis. Value: \"none\", "
+    "\"basic-inlining\", \"inlining\", \"dynamic\", \"dynamic-bifurcate\".",
+    /* SHALLOW_VAL */ "inlining", /* DEEP_VAL */ "dynamic-bifurcate")
+
 #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
 #undef ANALYZER_OPTION

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Thu Aug 15 18:53:14 2019
@@ -164,7 +164,40 @@ public:
   using ConfigTable = llvm::StringMap<std::string>;
 
   static std::vector<StringRef>
-  getRegisteredCheckers(bool IncludeExperimental = false);
+  getRegisteredCheckers(bool IncludeExperimental = false) {
+    static const StringRef StaticAnalyzerChecks[] = {
+#define GET_CHECKERS
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) FULLNAME,
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef CHECKER
+#undef GET_CHECKERS
+    };
+    std::vector<StringRef> Checkers;
+    for (StringRef CheckerName : StaticAnalyzerChecks) {
+      if (!CheckerName.startswith("debug.") &&
+          (IncludeExperimental || !CheckerName.startswith("alpha.")))
+        Checkers.push_back(CheckerName);
+    }
+    return Checkers;
+  }
+
+  static std::vector<StringRef>
+  getRegisteredPackages(bool IncludeExperimental = false) {
+    static const StringRef StaticAnalyzerPackages[] = {
+#define GET_PACKAGES
+#define PACKAGE(FULLNAME) FULLNAME,
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef PACKAGE
+#undef GET_PACKAGES
+    };
+    std::vector<StringRef> Packages;
+    for (StringRef PackageName : StaticAnalyzerPackages) {
+      if (PackageName != "debug" &&
+          (IncludeExperimental || PackageName != "alpha"))
+        Packages.push_back(PackageName);
+    }
+    return Packages;
+  }
 
   /// Convenience function for printing options or checkers and their
   /// description in a formatted manner. If \p MinLineWidth is set to 0, no line
@@ -188,9 +221,11 @@ public:
       std::pair<StringRef, StringRef> EntryDescPair,
       size_t EntryWidth, size_t InitialPad, size_t MinLineWidth = 0);
 
+  /// Pairs of checker/package name and enable/disable.
+  std::vector<std::pair<std::string, bool>> CheckersAndPackages;
 
-  /// Pair of checker name and enable/disable.
-  std::vector<std::pair<std::string, bool>> CheckersControlList;
+  /// Vector of checker/package names which will not emit warnings.
+  std::vector<std::string> SilencedCheckersAndPackages;
 
   /// A key-value table of use-specified configuration values.
   // TODO: This shouldn't be public.

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Thu Aug 15 18:53:14 2019
@@ -324,18 +324,18 @@ static bool ParseAnalyzerArgs(AnalyzerOp
       getLastArgIntValue(Args, OPT_analyzer_inline_max_stack_depth,
                          Opts.InlineMaxStackDepth, Diags);
 
-  Opts.CheckersControlList.clear();
+  Opts.CheckersAndPackages.clear();
   for (const Arg *A :
        Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) {
     A->claim();
-    bool enable = (A->getOption().getID() == OPT_analyzer_checker);
+    bool IsEnabled = A->getOption().getID() == OPT_analyzer_checker;
     // We can have a list of comma separated checker names, e.g:
     // '-analyzer-checker=cocoa,unix'
-    StringRef checkerList = A->getValue();
-    SmallVector<StringRef, 4> checkers;
-    checkerList.split(checkers, ",");
-    for (auto checker : checkers)
-      Opts.CheckersControlList.emplace_back(checker, enable);
+    StringRef CheckerAndPackageList = A->getValue();
+    SmallVector<StringRef, 16> CheckersAndPackages;
+    CheckerAndPackageList.split(CheckersAndPackages, ",");
+    for (const StringRef CheckerOrPackage : CheckersAndPackages)
+      Opts.CheckersAndPackages.emplace_back(CheckerOrPackage, IsEnabled);
   }
 
   // Go through the analyzer configuration options.
@@ -479,6 +479,32 @@ static void parseAnalyzerConfigs(Analyze
       !llvm::sys::fs::is_directory(AnOpts.ModelPath))
     Diags->Report(diag::err_analyzer_config_invalid_input) << "model-path"
                                                            << "a filename";
+
+  // FIXME: Here we try to validate the silenced checkers or packages are valid.
+  // The current approach only validates the registered checkers which does not
+  // contain the runtime enabled checkers and optimally we would validate both.
+  if (!AnOpts.RawSilencedCheckersAndPackages.empty()) {
+    std::vector<StringRef> Checkers =
+        AnOpts.getRegisteredCheckers(/*IncludeExperimental=*/true);
+    std::vector<StringRef> Packages =
+        AnOpts.getRegisteredPackages(/*IncludeExperimental=*/true);
+
+    SmallVector<StringRef, 16> CheckersAndPackages;
+    AnOpts.RawSilencedCheckersAndPackages.split(CheckersAndPackages, ";");
+
+    for (const StringRef CheckerOrPackage : CheckersAndPackages) {
+      bool IsChecker = CheckerOrPackage.contains('.');
+      bool IsValidName =
+          IsChecker ? llvm::find(Checkers, CheckerOrPackage) != Checkers.end()
+                    : llvm::find(Packages, CheckerOrPackage) != Packages.end();
+
+      if (!IsValidName)
+        Diags->Report(diag::err_unknown_analyzer_checker_or_package)
+            << CheckerOrPackage;
+
+      AnOpts.SilencedCheckersAndPackages.emplace_back(CheckerOrPackage);
+    }
+  }
 }
 
 static bool ParseMigratorArgs(MigratorOptions &Opts, ArgList &Args) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Thu Aug 15 18:53:14 2019
@@ -30,25 +30,6 @@ using namespace clang;
 using namespace ento;
 using namespace llvm;
 
-std::vector<StringRef>
-AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) {
-  static const StringRef StaticAnalyzerChecks[] = {
-#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN)                 \
-  FULLNAME,
-#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
-#undef CHECKER
-#undef GET_CHECKERS
-  };
-  std::vector<StringRef> Result;
-  for (StringRef CheckName : StaticAnalyzerChecks) {
-    if (!CheckName.startswith("debug.") &&
-        (IncludeExperimental || !CheckName.startswith("alpha.")))
-      Result.push_back(CheckName);
-  }
-  return Result;
-}
-
 void AnalyzerOptions::printFormattedEntry(
     llvm::raw_ostream &Out,
     std::pair<StringRef, StringRef> EntryDescPair,

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Thu Aug 15 18:53:14 2019
@@ -1924,15 +1924,22 @@ PathDiagnosticBuilder::PathDiagnosticBui
 
 std::unique_ptr<PathDiagnostic>
 PathDiagnosticBuilder::generate(const PathDiagnosticConsumer *PDC) const {
-
-  if (!PDC->shouldGenerateDiagnostics())
-    return generateEmptyDiagnosticForReport(R, getSourceManager());
-
   PathDiagnosticConstruct Construct(PDC, ErrorNode, R);
 
   const SourceManager &SM = getSourceManager();
   const BugReport *R = getBugReport();
   const AnalyzerOptions &Opts = getAnalyzerOptions();
+  StringRef ErrorTag = ErrorNode->getLocation().getTag()->getTagDescription();
+
+  // See whether we need to silence the checker/package.
+  // FIXME: This will not work if the report was emitted with an incorrect tag.
+  for (const std::string &CheckerOrPackage : Opts.SilencedCheckersAndPackages) {
+    if (ErrorTag.startswith(CheckerOrPackage))
+      return nullptr;
+  }
+
+  if (!PDC->shouldGenerateDiagnostics())
+    return generateEmptyDiagnosticForReport(R, getSourceManager());
 
   // Construct the final (warning) event for the bug report.
   auto EndNotes = VisitorsDiagnostics->find(ErrorNode);
@@ -2029,7 +2036,6 @@ PathDiagnosticBuilder::generate(const Pa
   return std::move(Construct.PD);
 }
 
-
 //===----------------------------------------------------------------------===//
 // Methods for BugType and subclasses.
 //===----------------------------------------------------------------------===//
@@ -2646,9 +2652,13 @@ GRBugReporter::generatePathDiagnostics(
   Optional<PathDiagnosticBuilder> PDB =
       PathDiagnosticBuilder::findValidReport(bugReports, *this);
 
-  if (PDB)
-    for (PathDiagnosticConsumer *PC : consumers)
-      (*Out)[PC] = PDB->generate(PC);
+  if (PDB) {
+    for (PathDiagnosticConsumer *PC : consumers) {
+      if (std::unique_ptr<PathDiagnostic> PD = PDB->generate(PC)) {
+        (*Out)[PC] = std::move(PD);
+      }
+    }
+  }
 
   return Out;
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp Thu Aug 15 18:53:14 2019
@@ -200,12 +200,12 @@ CheckerRegistry::CheckerRegistry(
 
   // 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.CheckersAndPackages) {
     CheckerInfoListRange CheckerForCmdLineArg =
         getMutableCheckersForCmdLineArg(Opt.first);
 
     if (CheckerForCmdLineArg.begin() == CheckerForCmdLineArg.end()) {
-      Diags.Report(diag::err_unknown_analyzer_checker) << Opt.first;
+      Diags.Report(diag::err_unknown_analyzer_checker_or_package) << Opt.first;
       Diags.Report(diag::note_suggest_disabling_all_checkers);
     }
 
@@ -468,9 +468,10 @@ isOptionContainedIn(const CheckerRegistr
 void CheckerRegistry::validateCheckerOptions() const {
   for (const auto &Config : AnOpts.Config) {
 
-    StringRef SuppliedChecker;
+    StringRef SuppliedCheckerOrPackage;
     StringRef SuppliedOption;
-    std::tie(SuppliedChecker, SuppliedOption) = Config.getKey().split(':');
+    std::tie(SuppliedCheckerOrPackage, SuppliedOption) =
+        Config.getKey().split(':');
 
     if (SuppliedOption.empty())
       continue;
@@ -483,21 +484,24 @@ void CheckerRegistry::validateCheckerOpt
     // Since lower_bound would look for the first element *not less* than "cor",
     // it would return with an iterator to the first checker in the core, so we
     // we really have to use find here, which uses operator==.
-    auto CheckerIt = llvm::find(Checkers, CheckerInfo(SuppliedChecker));
+    auto CheckerIt =
+        llvm::find(Checkers, CheckerInfo(SuppliedCheckerOrPackage));
     if (CheckerIt != Checkers.end()) {
-      isOptionContainedIn(CheckerIt->CmdLineOptions, SuppliedChecker,
+      isOptionContainedIn(CheckerIt->CmdLineOptions, SuppliedCheckerOrPackage,
                           SuppliedOption, AnOpts, Diags);
       continue;
     }
 
-    auto PackageIt = llvm::find(Packages, PackageInfo(SuppliedChecker));
+    auto PackageIt =
+        llvm::find(Packages, PackageInfo(SuppliedCheckerOrPackage));
     if (PackageIt != Packages.end()) {
-      isOptionContainedIn(PackageIt->CmdLineOptions, SuppliedChecker,
+      isOptionContainedIn(PackageIt->CmdLineOptions, SuppliedCheckerOrPackage,
                           SuppliedOption, AnOpts, Diags);
       continue;
     }
 
-    Diags.Report(diag::err_unknown_analyzer_checker) << SuppliedChecker;
+    Diags.Report(diag::err_unknown_analyzer_checker_or_package)
+        << SuppliedCheckerOrPackage;
   }
 }
 

Modified: cfe/trunk/test/Analysis/analyzer-config.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-config.c?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/analyzer-config.c (original)
+++ cfe/trunk/test/Analysis/analyzer-config.c Thu Aug 15 18:53:14 2019
@@ -82,6 +82,7 @@
 // CHECK-NEXT: region-store-small-struct-limit = 2
 // CHECK-NEXT: report-in-main-source-file = false
 // CHECK-NEXT: serialize-stats = false
+// CHECK-NEXT: silence-checkers = ""
 // CHECK-NEXT: stable-report-filename = false
 // CHECK-NEXT: suppress-c++-stdlib = true
 // CHECK-NEXT: suppress-inlined-defensive-checks = true
@@ -92,4 +93,4 @@
 // CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 89
+// CHECK-NEXT: num-entries = 90

Added: cfe/trunk/test/Analysis/silence-checkers-and-packages-core-all.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/silence-checkers-and-packages-core-all.cpp?rev=369078&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/silence-checkers-and-packages-core-all.cpp (added)
+++ cfe/trunk/test/Analysis/silence-checkers-and-packages-core-all.cpp Thu Aug 15 18:53:14 2019
@@ -0,0 +1,39 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=core -analyzer-config \
+// RUN:   silence-checkers=core \
+// RUN:  -verify %s
+
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=core -analyzer-config \
+// RUN:   silence-checkers="core.DivideZero;core.NullDereference" \
+// RUN:  -verify %s
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:  -analyzer-checker=core -analyzer-config \
+// RUN:   silence-checkers=core.NullDeref \
+// RUN:  2>&1 | FileCheck %s -check-prefix=CHECK-CHECKER-ERROR
+
+// CHECK-CHECKER-ERROR:      (frontend): no analyzer checkers or packages
+// CHECK-CHECKER-ERROR-SAME:             are associated with 'core.NullDeref'
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:  -analyzer-checker=core -analyzer-config \
+// RUN:   silence-checkers=coreModeling \
+// RUN:  2>&1 | FileCheck %s -check-prefix=CHECK-PACKAGE-ERROR
+
+// CHECK-PACKAGE-ERROR:      (frontend): no analyzer checkers or packages
+// CHECK-PACKAGE-ERROR-SAME:             are associated with 'coreModeling'
+
+void test_disable_core_div_by_zero() {
+  (void)(1 / 0);
+  // expected-warning at -1 {{division by zero is undefined}}
+  // no-warning: 'Division by zero'
+}
+
+void test_disable_null_deref(int *p) {
+  if (p)
+    return;
+
+  int x = p[0];
+  // no-warning: Array access (from variable 'p') results in a null pointer dereference
+}

Added: cfe/trunk/test/Analysis/silence-checkers-and-packages-core-div-by-zero.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/silence-checkers-and-packages-core-div-by-zero.cpp?rev=369078&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/silence-checkers-and-packages-core-div-by-zero.cpp (added)
+++ cfe/trunk/test/Analysis/silence-checkers-and-packages-core-div-by-zero.cpp Thu Aug 15 18:53:14 2019
@@ -0,0 +1,18 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=core -analyzer-config \
+// RUN:   silence-checkers=core.DivideZero \
+// RUN:  -verify %s
+
+void test_disable_core_div_by_zero() {
+  (void)(1 / 0);
+  // expected-warning at -1 {{division by zero is undefined}}
+  // no-warning: 'Division by zero'
+}
+
+void test_disable_null_deref(int *p) {
+  if (p)
+    return;
+
+  int x = p[0];
+  // expected-warning at -1 {{Array access (from variable 'p') results in a null pointer dereference}}
+}

Modified: cfe/trunk/tools/scan-build/bin/scan-build
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build/bin/scan-build?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/tools/scan-build/bin/scan-build (original)
+++ cfe/trunk/tools/scan-build/bin/scan-build Thu Aug 15 18:53:14 2019
@@ -57,6 +57,7 @@ my %Options = (
   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 @@ sub ProcessArgs {
     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 are disabled/silenced.
+      # 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 @@ foreach (sort { $Options{DisableCheckers
   # Push checkers in order they were disabled.
   push @AnalysesToRun, "-analyzer-disable-checker", $_;
 }
+foreach (sort { $Options{SilenceCheckers}{$a} <=> $Options{SilenceCheckers}{$b} }
+         keys %{$Options{SilenceCheckers}}) {
+  # Push checkers in order they were silenced.
+  push @AnalysesToRun, "-analyzer-config 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}"; }

Modified: cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp?rev=369078&r1=369077&r2=369078&view=diff
==============================================================================
--- cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp (original)
+++ cfe/trunk/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp Thu Aug 15 18:53:14 2019
@@ -46,7 +46,7 @@ public:
     std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer =
         CreateAnalysisConsumer(Compiler);
     AnalysisConsumer->AddDiagnosticConsumer(new DiagConsumer(DiagsOutput));
-    Compiler.getAnalyzerOpts()->CheckersControlList = {
+    Compiler.getAnalyzerOpts()->CheckersAndPackages = {
         {"custom.CustomChecker", true}};
     AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
       Registry.addChecker<CheckerT>("custom.CustomChecker", "Description", "");




More information about the cfe-commits mailing list