diff options
author | Kristof Umann <kristof.umann@ericsson.com> | 2019-05-23 21:46:51 +0000 |
---|---|---|
committer | Kristof Umann <kristof.umann@ericsson.com> | 2019-05-23 21:46:51 +0000 |
commit | 5bc40d9b188bb43e2aafafe58d8d169cc7c9b4f1 (patch) | |
tree | 3578e16536f1d42617a6c2894cb588bcd8f825d8 | |
parent | a85c0fd918749fe88c3a3bbc5ca23061e88b4536 (diff) | |
download | llvm-5bc40d9b188bb43e2aafafe58d8d169cc7c9b4f1.zip llvm-5bc40d9b188bb43e2aafafe58d8d169cc7c9b4f1.tar.gz llvm-5bc40d9b188bb43e2aafafe58d8d169cc7c9b4f1.tar.bz2 |
[analyzer] List checkers in 3 categories: released, alpha, developer
Previously, the only way to display the list of available checkers was
to invoke the analyzer with -analyzer-checker-help frontend flag. This
however wasn't really great from a maintainer standpoint: users came
across checkers meant strictly for development purposes that weren't to
be tinkered with, or those that were still in development. This patch
creates a clearer division in between these categories.
From now on, we'll have 3 flags to display the list checkers. These
lists are mutually exclusive and can be used in any combination (for
example to display both stable and alpha checkers).
-analyzer-checker-help: Displays the list for stable, production ready
checkers.
-analyzer-checker-help-alpha: Displays the list for in development
checkers. Enabling is discouraged
for non-development purposes.
-analyzer-checker-help-developer: Modeling and debug checkers. Modeling
checkers shouldn't be enabled/disabled
by hand, and debug checkers shouldn't
be touched by users.
Differential Revision: https://reviews.llvm.org/D62093
llvm-svn: 361558
-rw-r--r-- | clang/include/clang/Driver/CC1Options.td | 11 | ||||
-rw-r--r-- | clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td | 4 | ||||
-rw-r--r-- | clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h | 16 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 4 | ||||
-rw-r--r-- | clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp | 31 | ||||
-rw-r--r-- | clang/test/Analysis/show-checker-list.c | 63 |
7 files changed, 107 insertions, 25 deletions
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index f7da374..7605b3f 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -130,9 +130,14 @@ def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">, def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">, HelpText<"Display the list of analyzer checkers that are available">; -def analyzer_checker_help_hidden : Flag<["-"], "analyzer-checker-help-hidden">, - HelpText<"Display the list of analyzer checkers that are available, " - "including modeling checkers">; +def analyzer_checker_help_alpha : Flag<["-"], "analyzer-checker-help-alpha">, + HelpText<"Display the list of in development analyzer checkers. These " + "are NOT considered safe, they are unstable and will emit incorrect " + "reports. Enable ONLY FOR DEVELOPMENT purposes">; + +def analyzer_checker_help_developer : Flag<["-"], "analyzer-checker-help-developer">, + HelpText<"Display the list of developer-only checkers such as modeling " + "and debug checkers">; def analyzer_config_help : Flag<["-"], "analyzer-config-help">, HelpText<"Display the list of -analyzer-config options">; diff --git a/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td index c381d4b..3c7c6fe9 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td @@ -111,6 +111,6 @@ class Dependencies<list<Checker> Deps = []> { list<Checker> Dependencies = Deps; } -/// Marks a checker or a package hidden. Hidden entries won't be displayed in -/// -analyzer-checker-help, which is desirable for alpha or modeling checkers. +/// Marks a checker or a package hidden. Hidden entries are meant for developers +/// only, and aren't exposed to end users. class Hidden { bit Hidden = 1; } diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index 6a54e15..1c45ffd 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -220,7 +220,8 @@ public: unsigned DisableAllChecks : 1; unsigned ShowCheckerHelp : 1; - unsigned ShowCheckerHelpHidden : 1; + unsigned ShowCheckerHelpAlpha : 1; + unsigned ShowCheckerHelpDeveloper : 1; unsigned ShowEnabledCheckerList : 1; unsigned ShowCheckerOptionList : 1; unsigned ShowConfigOptionsList : 1; @@ -285,12 +286,13 @@ public: AnalyzerOptions() : DisableAllChecks(false), ShowCheckerHelp(false), - ShowCheckerHelpHidden(false), ShowEnabledCheckerList(false), - ShowCheckerOptionList(false), ShowConfigOptionsList(false), - AnalyzeAll(false), AnalyzerDisplayProgress(false), - AnalyzeNestedBlocks(false), eagerlyAssumeBinOpBifurcation(false), - TrimGraph(false), visualizeExplodedGraphWithGraphViz(false), - UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false) { + ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false), + ShowEnabledCheckerList(false), ShowCheckerOptionList(false), + ShowConfigOptionsList(false), AnalyzeAll(false), + AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false), + eagerlyAssumeBinOpBifurcation(false), TrimGraph(false), + visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false), + PrintStats(false), NoRetryExhausted(false) { llvm::sort(AnalyzerConfigCmdFlags); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 877e70b..34693af 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -285,7 +285,9 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, } Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help); - Opts.ShowCheckerHelpHidden = Args.hasArg(OPT_analyzer_checker_help_hidden); + Opts.ShowCheckerHelpAlpha = Args.hasArg(OPT_analyzer_checker_help_alpha); + Opts.ShowCheckerHelpDeveloper = + Args.hasArg(OPT_analyzer_checker_help_developer); Opts.ShowCheckerOptionList = Args.hasArg(OPT_analyzer_checker_option_help); Opts.ShowConfigOptionsList = Args.hasArg(OPT_analyzer_config_help); Opts.ShowEnabledCheckerList = Args.hasArg(OPT_analyzer_list_enabled_checkers); diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 27690be..ea720c8 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -238,7 +238,8 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) { AnalyzerOptions &AnOpts = *Clang->getAnalyzerOpts(); // Honor -analyzer-checker-help and -analyzer-checker-help-hidden. - if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpHidden) { + if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha || + AnOpts.ShowCheckerHelpDeveloper) { ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins, AnOpts, diff --git a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp index d405933..5f96389 100644 --- a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -514,13 +514,36 @@ void CheckerRegistry::printCheckerWithDescList(raw_ostream &Out, } const size_t InitialPad = 2; - for (const auto &Checker : Checkers) { - if (!AnOpts.ShowCheckerHelpHidden && Checker.IsHidden) - continue; - AnalyzerOptions::printFormattedEntry(Out, {Checker.FullName, Checker.Desc}, + auto Print = [=](llvm::raw_ostream &Out, const CheckerInfo &Checker, + StringRef Description) { + AnalyzerOptions::printFormattedEntry(Out, {Checker.FullName, Description}, InitialPad, OptionFieldWidth); Out << '\n'; + }; + + for (const auto &Checker : Checkers) { + // The order of this if branches is significant, we wouldn't like to display + // developer checkers even in the alpha output. For example, + // alpha.cplusplus.IteratorModeling is a modeling checker, hence it's hidden + // by default, and users (even when the user is a developer of an alpha + // checker) shouldn't normally tinker with whether they should be enabled. + + if (Checker.IsHidden) { + if (AnOpts.ShowCheckerHelpDeveloper) + Print(Out, Checker, Checker.Desc); + continue; + } + + if (Checker.FullName.startswith("alpha")) { + if (AnOpts.ShowCheckerHelpAlpha) + Print(Out, Checker, + ("(Enable only for development!) " + Checker.Desc).str()); + continue; + } + + if (AnOpts.ShowCheckerHelp) + Print(Out, Checker, Checker.Desc); } } diff --git a/clang/test/Analysis/show-checker-list.c b/clang/test/Analysis/show-checker-list.c index 83ed6e4..3d354c3 100644 --- a/clang/test/Analysis/show-checker-list.c +++ b/clang/test/Analysis/show-checker-list.c @@ -1,11 +1,60 @@ // RUN: %clang_cc1 -analyzer-checker-help \ -// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE -// RUN: %clang_cc1 -analyzer-checker-help-hidden \ -// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-HIDDEN +// RUN: %clang_cc1 -analyzer-checker-help-alpha \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-ALPHA -// CHECK: core.DivideZero -// CHECK-HIDDEN: core.DivideZero +// RUN: %clang_cc1 -analyzer-checker-help-developer \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-DEVELOPER -// CHECK-NOT: unix.DynamicMemoryModeling -// CHECK-HIDDEN: unix.DynamicMemoryModeling +// RUN: %clang_cc1 -analyzer-checker-help-developer \ +// RUN: -analyzer-checker-help-alpha \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-DEVELOPER-ALPHA + +// RUN: %clang_cc1 -analyzer-checker-help \ +// RUN: -analyzer-checker-help-alpha \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE-ALPHA + +// RUN: %clang_cc1 -analyzer-checker-help \ +// RUN: -analyzer-checker-help-developer \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE-DEVELOPER + +// RUN: %clang_cc1 -analyzer-checker-help \ +// RUN: -analyzer-checker-help-alpha \ +// RUN: -analyzer-checker-help-developer \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE-ALPHA-DEVELOPER + +// CHECK-STABLE-NOT: alpha.unix.Chroot +// CHECK-DEVELOPER-NOT: alpha.unix.Chroot +// CHECK-ALPHA: alpha.unix.Chroot + +// Note that alpha.cplusplus.IteratorModeling is not only an alpha, but also a +// hidden checker. In this case, we'd only like to see it in the developer list. +// CHECK-ALPHA-NOT: alpha.cplusplus.IteratorModeling +// CHECK-DEVELOPER: alpha.cplusplus.IteratorModeling + +// CHECK-STABLE: core.DivideZero +// CHECK-DEVELOPER-NOT: core.DivideZero +// CHECK-ALPHA-NOT: core.DivideZero + +// CHECK-STABLE-NOT: debug.ConfigDumper +// CHECK-DEVELOPER: debug.ConfigDumper +// CHECK-ALPHA-NOT: debug.ConfigDumper + + +// CHECK-STABLE-ALPHA: alpha.unix.Chroot +// CHECK-DEVELOPER-ALPHA: alpha.unix.Chroot +// CHECK-STABLE-DEVELOPER-NOT: alpha.unix.Chroot + +// CHECK-STABLE-ALPHA: core.DivideZero +// CHECK-DEVELOPER-ALPHA-NOT: core.DivideZero +// CHECK-STABLE-DEVELOPER: core.DivideZero + +// CHECK-STABLE-ALPHA-NOT: debug.ConfigDumper +// CHECK-DEVELOPER-ALPHA: debug.ConfigDumper +// CHECK-STABLE-DEVELOPER: debug.ConfigDumper + + +// CHECK-STABLE-ALPHA-DEVELOPER: alpha.unix.Chroot +// CHECK-STABLE-ALPHA-DEVELOPER: core.DivideZero +// CHECK-STABLE-ALPHA-DEVELOPER: debug.ConfigDumper |