r362855 - [analyzer] Add werror flag for analyzer warnings

Keno Fischer via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 7 16:34:00 PDT 2019


Author: kfischer
Date: Fri Jun  7 16:34:00 2019
New Revision: 362855

URL: http://llvm.org/viewvc/llvm-project?rev=362855&view=rev
Log:
[analyzer] Add werror flag for analyzer warnings

Summary:
We're using the clang static analyzer together with a number of
custom analyses in our CI system to ensure that certain invariants
are statiesfied for by the code every commit. Unfortunately, there
currently doesn't seem to be a good way to determine whether any
analyzer warnings were emitted, other than parsing clang's output
(or using scan-build, which then in turn parses clang's output).
As a simpler mechanism, simply add a `-analyzer-werror` flag to CC1
that causes the analyzer to emit its warnings as errors instead.
I briefly tried to have this be `Werror=analyzer` and make it go
through that machinery instead, but that seemed more trouble than
it was worth in terms of conflicting with options to the actual build
and special cases that would be required to circumvent the analyzers
usual attempts to quiet non-analyzer warnings. This is simple and it
works well.

Reviewed-By: NoQ, Szelethusw
Differential Revision: https://reviews.llvm.org/D62885

Modified:
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
    cfe/trunk/test/Analysis/override-werror.c

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=362855&r1=362854&r2=362855&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Fri Jun  7 16:34:00 2019
@@ -166,6 +166,9 @@ def analyzer_config_compatibility_mode :
 def analyzer_config_compatibility_mode_EQ : Joined<["-"], "analyzer-config-compatibility-mode=">,
   Alias<analyzer_config_compatibility_mode>;
 
+def analyzer_werror : Flag<["-"], "analyzer-werror">,
+  HelpText<"Emit analyzer results as errors rather than warnings">;
+
 //===----------------------------------------------------------------------===//
 // Migrator Options
 //===----------------------------------------------------------------------===//

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=362855&r1=362854&r2=362855&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Fri Jun  7 16:34:00 2019
@@ -245,6 +245,9 @@ public:
   /// strategy. We get better code coverage when retry is enabled.
   unsigned NoRetryExhausted : 1;
 
+  /// Emit analyzer warnings as errors.
+  unsigned AnalyzerWerror : 1;
+
   /// The inlining stack depth limit.
   // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
   unsigned InlineMaxStackDepth = 5;
@@ -297,7 +300,7 @@ public:
         AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
         eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
         visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
-        PrintStats(false), NoRetryExhausted(false) {
+        PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {
     llvm::sort(AnalyzerConfigCmdFlags);
   }
 

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=362855&r1=362854&r2=362855&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Jun  7 16:34:00 2019
@@ -309,6 +309,7 @@ static bool ParseAnalyzerArgs(AnalyzerOp
     Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
   Opts.DumpExplodedGraphTo = Args.getLastArgValue(OPT_analyzer_dump_egraph);
   Opts.NoRetryExhausted = Args.hasArg(OPT_analyzer_disable_retry_exhausted);
+  Opts.AnalyzerWerror = Args.hasArg(OPT_analyzer_werror);
   Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers);
   Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress);
   Opts.AnalyzeNestedBlocks =

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=362855&r1=362854&r2=362855&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Fri Jun  7 16:34:00 2019
@@ -83,10 +83,11 @@ void ento::createTextPathDiagnosticConsu
 namespace {
 class ClangDiagPathDiagConsumer : public PathDiagnosticConsumer {
   DiagnosticsEngine &Diag;
-  bool IncludePath;
+  bool IncludePath, ShouldEmitAsError;
+
 public:
   ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag)
-    : Diag(Diag), IncludePath(false) {}
+      : Diag(Diag), IncludePath(false), ShouldEmitAsError(false) {}
   ~ClangDiagPathDiagConsumer() override {}
   StringRef getName() const override { return "ClangDiags"; }
 
@@ -101,9 +102,14 @@ public:
     IncludePath = true;
   }
 
+  void enableWerror() { ShouldEmitAsError = true; }
+
   void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
                             FilesMade *filesMade) override {
-    unsigned WarnID = Diag.getCustomDiagID(DiagnosticsEngine::Warning, "%0");
+    unsigned WarnID =
+        ShouldEmitAsError
+            ? Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0")
+            : Diag.getCustomDiagID(DiagnosticsEngine::Warning, "%0");
     unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note, "%0");
 
     for (std::vector<const PathDiagnostic*>::iterator I = Diags.begin(),
@@ -225,6 +231,9 @@ public:
           new ClangDiagPathDiagConsumer(PP.getDiagnostics());
       PathConsumers.push_back(clangDiags);
 
+      if (Opts->AnalyzerWerror)
+        clangDiags->enableWerror();
+
       if (Opts->AnalysisDiagOpt == PD_TEXT) {
         clangDiags->enablePaths();
 
@@ -358,7 +367,7 @@ public:
       return true;
 
     llvm::Expected<const VarDecl *> CTUDeclOrError =
-      CTU.getCrossTUDefinition(VD, Opts->CTUDir, Opts->CTUIndexName, 
+      CTU.getCrossTUDefinition(VD, Opts->CTUDir, Opts->CTUIndexName,
                                Opts->DisplayCTUProgress);
 
     if (!CTUDeclOrError) {

Modified: cfe/trunk/test/Analysis/override-werror.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/override-werror.c?rev=362855&r1=362854&r2=362855&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/override-werror.c (original)
+++ cfe/trunk/test/Analysis/override-werror.c Fri Jun  7 16:34:00 2019
@@ -1,14 +1,17 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -Werror %s -analyzer-store=region -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -Werror %s -analyzer-store=region -analyzer-werror -verify=werror
 
 // This test case illustrates that using '-analyze' overrides the effect of
 // -Werror.  This allows basic warnings not to interfere with producing
 // analyzer results.
 
-char* f(int *p) { 
-  return p; // expected-warning{{incompatible pointer types}}
+char* f(int *p) {
+  return p; // expected-warning{{incompatible pointer types}} \
+               werror-warning{{incompatible pointer types}}
 }
 
 void g(int *p) {
-  if (!p) *p = 0; // expected-warning{{null}}  
+  if (!p) *p = 0; // expected-warning{{null}} \
+                     werror-error{{null}}
 }
 




More information about the cfe-commits mailing list