From d5478fdd8f054ceff9c64636c4ac65a256fcd69a Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Fri, 29 Aug 2014 20:01:38 +0000 Subject: [PATCH] Add an option to silence all analyzer warnings. People have been incorrectly using "-analyzer-disable-checker" to silence analyzer warnings on a file, when analyzing a project. Add the "-analyzer-disable-all-checks" option, which would allow the suppression and suggest it as part of the error message for "-analyzer-disable-checker". The idea here is to compose this with "--analyze" so that users can selectively opt out specific files from static analysis. llvm-svn: 216763 --- clang/include/clang/Basic/DiagnosticFrontendKinds.td | 3 +++ clang/include/clang/Driver/CC1Options.td | 3 +++ .../clang/StaticAnalyzer/Core/AnalyzerOptions.h | 8 ++++++++ clang/lib/Frontend/CompilerInvocation.cpp | 2 ++ clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp | 7 ++++++- .../StaticAnalyzer/Frontend/CheckerRegistration.cpp | 5 ++++- clang/test/Analysis/disable-all-checks.c | 10 ++++++++++ 7 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 clang/test/Analysis/disable-all-checks.c diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index eed107e9006c..c0c2227d86c0 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -135,6 +135,9 @@ def warn_unknown_warning_specifier : Warning< def err_unknown_analyzer_checker : Error< "no analyzer checkers are associated with '%0'">; +def note_suggest_disabling_all_checkers : Note< + "use -analyzer-disable-all-checks to disable all static analyzer checkers">; + def warn_incompatible_analyzer_plugin_api : Warning< "checker plugin '%0' is not compatible with this version of the analyzer">, InGroup >; diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index 7e6a3395221f..a1842d0efce0 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -108,6 +108,9 @@ def analyzer_disable_checker : Separate<["-"], "analyzer-disable-checker">, def analyzer_disable_checker_EQ : Joined<["-"], "analyzer-disable-checker=">, Alias; +def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">, + HelpText<"Disable all static analyzer checks">; + def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">, HelpText<"Display the list of analyzer checkers that are available">; diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index 266174375bb5..fc9fc5ee7931 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -137,6 +137,13 @@ public: unsigned maxBlockVisitOnPath; + /// \brief Disable all analyzer checks. + /// + /// This flag allows one to disable analyzer checks on the code processed by + /// the given analysis consumer. Note, the code will get parsed and the + /// command-line options will get checked. + unsigned DisableAllChecks : 1; + unsigned ShowCheckerHelp : 1; unsigned AnalyzeAll : 1; unsigned AnalyzerDisplayProgress : 1; @@ -420,6 +427,7 @@ public: AnalysisConstraintsOpt(RangeConstraintsModel), AnalysisDiagOpt(PD_HTML), AnalysisPurgeOpt(PurgeStmt), + DisableAllChecks(0), ShowCheckerHelp(0), AnalyzeAll(0), AnalyzerDisplayProgress(0), diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 6c176e8c1a00..31b53a59d07d 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -215,6 +215,8 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, } Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help); + Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks); + Opts.visualizeExplodedGraphWithGraphViz = Args.hasArg(OPT_analyzer_viz_egraph_graphviz); Opts.visualizeExplodedGraphWithUbiGraph = diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 4e9ad71785a7..6e763c19a07f 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -314,7 +314,7 @@ public: /// analyzed. This allows to redefine the default inlining policies when /// analyzing a given function. ExprEngine::InliningModes - getInliningModeForFunction(const Decl *D, const SetOfConstDecls &Visited); + getInliningModeForFunction(const Decl *D, const SetOfConstDecls &Visited); /// \brief Build the call graph for all the top level decls of this TU and /// use it to define the order in which the functions should be visited. @@ -513,6 +513,11 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) return; + // Don't analyze if the user explicitly asked for no checks to be performed + // on this file. + if (Opts->DisableAllChecks) + return; + { if (TUTotalTimer) TUTotalTimer->startTimer(); diff --git a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp index e2577c3c729f..8b15c10fdce1 100644 --- a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -118,9 +118,12 @@ CheckerManager *ento::createCheckerManager(AnalyzerOptions &opts, checkerMgr->finishedCheckerRegistration(); for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) { - if (checkerOpts[i].isUnclaimed()) + if (checkerOpts[i].isUnclaimed()) { diags.Report(diag::err_unknown_analyzer_checker) << checkerOpts[i].getName(); + diags.Report(diag::note_suggest_disabling_all_checkers); + } + } return checkerMgr.release(); diff --git a/clang/test/Analysis/disable-all-checks.c b/clang/test/Analysis/disable-all-checks.c new file mode 100644 index 000000000000..d8e7e0b83c5a --- /dev/null +++ b/clang/test/Analysis/disable-all-checks.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-disable-all-checks -verify %s +// RUN: %clang_cc1 -analyze -analyzer-disable-all-checks -analyzer-checker=core -analyzer-store=region -verify %s +// RUN: not %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-disable-checker -verify %s 2>&1 | FileCheck %s +// expected-no-diagnostics + +// CHECK: use -analyzer-disable-all-checks to disable all static analyzer checkers +int buggy() { + int x = 0; + return 5/x; // no warning +} \ No newline at end of file