[flang][driver] Add options for -Werror
authorArnamoy Bhattacharyya <arnamoy.bhattacharyya@huawei.com>
Mon, 5 Apr 2021 16:41:46 +0000 (12:41 -0400)
committerArnamoy Bhattacharyya <arnamoy10@gmail.com>
Mon, 5 Apr 2021 16:47:52 +0000 (12:47 -0400)
With the option given, warnings are treated as error.

Reviewed By: awarzynski

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

12 files changed:
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Flang.cpp
flang/include/flang/Frontend/CompilerInvocation.h
flang/lib/Frontend/CompilerInvocation.cpp
flang/lib/Frontend/FrontendActions.cpp
flang/test/Driver/driver-help-hidden.f90
flang/test/Driver/driver-help.f90
flang/test/Driver/werror_parse.f [new file with mode: 0644]
flang/test/Driver/werror_scan.f [new file with mode: 0644]
flang/test/Driver/werror_sema.f90 [new file with mode: 0644]
flang/test/Driver/werror_wrong.f90 [new file with mode: 0644]
flang/tools/f18/f18.cpp

index 64d658b..38977cc 100644 (file)
@@ -746,7 +746,7 @@ def Wundef_prefix_EQ : CommaJoined<["-"], "Wundef-prefix=">, Group<W_value_Group
   MarshallingInfoStringVector<DiagnosticOpts<"UndefPrefixes">>;
 def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
 def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>;
-def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>,
+def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption, FC1Option, FlangOption]>,
   MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
 def Xanalyzer : Separate<["-"], "Xanalyzer">,
   HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">,
index bf2a19e..73dbeac 100644 (file)
@@ -44,7 +44,7 @@ void Flang::AddOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
   Args.AddAllArgs(CmdArgs,
                   {options::OPT_module_dir, options::OPT_fdebug_module_writer,
                    options::OPT_fintrinsic_modules_path, options::OPT_pedantic,
-                   options::OPT_std_EQ});
+                   options::OPT_std_EQ, options::OPT_W_Joined});
 }
 
 void Flang::ConstructJob(Compilation &C, const JobAction &JA,
index 99050dc..529f15e 100644 (file)
@@ -71,6 +71,8 @@ class CompilerInvocation : public CompilerInvocationBase {
 
   bool debugModuleDir_ = false;
 
+  bool warnAsErr_ = false;
+
   // Fortran Dialect options
   Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_;
 
@@ -98,6 +100,9 @@ public:
   bool &debugModuleDir() { return debugModuleDir_; }
   const bool &debugModuleDir() const { return debugModuleDir_; }
 
+  bool &warnAsErr() { return warnAsErr_; }
+  const bool &warnAsErr() const { return warnAsErr_; }
+
   bool &enableConformanceChecks() { return EnableConformanceChecks_; }
   const bool &enableConformanceChecks() const {
     return EnableConformanceChecks_;
@@ -126,6 +131,8 @@ public:
 
   void SetDebugModuleDir(bool flag) { debugModuleDir_ = flag; }
 
+  void SetWarnAsErr(bool flag) { warnAsErr_ = flag; }
+
   /// Set the Fortran options to predifined defaults. These defaults are
   /// consistend with f18/f18.cpp.
   // TODO: We should map frontendOpts_ to parserOpts_ instead. For that, we
index 3bd541e..ce7392c 100644 (file)
@@ -350,6 +350,26 @@ static void parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
   }
 }
 
+/// Parses all diagnostics related arguments and populates the variables
+/// options accordingly.
+static void parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
+    clang::DiagnosticsEngine &diags) {
+  // -Werror option
+  // TODO: Currently throws a Diagnostic for anything other than -W<error>,
+  // this has to change when other -W<opt>'s are supported.
+  if (args.hasArg(clang::driver::options::OPT_W_Joined)) {
+    if (args.getLastArgValue(clang::driver::options::OPT_W_Joined)
+            .equals("error")) {
+      res.SetWarnAsErr(true);
+    } else {
+      const unsigned diagID =
+          diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
+              "Only `-Werror` is supported currently.");
+      diags.Report(diagID);
+    }
+  }
+}
+
 /// Parses all Dialect related arguments and populates the variables
 /// options accordingly.
 static void parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
@@ -445,6 +465,8 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &res,
   parseSemaArgs(res, args, diags);
   // Parse dialect arguments
   parseDialectArgs(res, args, diags);
+  // Parse diagnostic arguments
+  parseDiagArgs(res, args, diags);
 
   return success;
 }
@@ -574,5 +596,6 @@ void CompilerInvocation::setSemanticsOpts(
 
   semanticsContext_->set_moduleDirectory(moduleDir())
       .set_searchDirectories(fortranOptions.searchDirectories)
-      .set_warnOnNonstandardUsage(enableConformanceChecks());
+      .set_warnOnNonstandardUsage(enableConformanceChecks())
+      .set_warningsAreErrors(warnAsErr());
 }
index 1871a35..f5420c2 100644 (file)
@@ -64,7 +64,9 @@ bool PrescanAction::BeginSourceFileAction(CompilerInstance &c1) {
   // Prescan. In case of failure, report and return.
   ci.parsing().Prescan(currentInputPath, parserOptions);
 
-  if (ci.parsing().messages().AnyFatalError()) {
+  if (!ci.parsing().messages().empty() &&
+      (ci.invocation().warnAsErr() ||
+          ci.parsing().messages().AnyFatalError())) {
     const unsigned diagID = ci.diagnostics().getCustomDiagID(
         clang::DiagnosticsEngine::Error, "Could not scan %0");
     ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName();
@@ -97,7 +99,9 @@ bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) {
   // Prescan. In case of failure, report and return.
   ci.parsing().Prescan(currentInputPath, parserOptions);
 
-  if (ci.parsing().messages().AnyFatalError()) {
+  if (!ci.parsing().messages().empty() &&
+      (ci.invocation().warnAsErr() ||
+          ci.parsing().messages().AnyFatalError())) {
     const unsigned diagID = ci.diagnostics().getCustomDiagID(
         clang::DiagnosticsEngine::Error, "Could not scan %0");
     ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName();
@@ -109,7 +113,9 @@ bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) {
   // Parse. In case of failure, report and return.
   ci.parsing().Parse(llvm::outs());
 
-  if (ci.parsing().messages().AnyFatalError()) {
+  if (!ci.parsing().messages().empty() &&
+      (ci.invocation().warnAsErr() ||
+          ci.parsing().messages().AnyFatalError())) {
     unsigned diagID = ci.diagnostics().getCustomDiagID(
         clang::DiagnosticsEngine::Error, "Could not parse %0");
     ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName();
@@ -264,7 +270,9 @@ void DebugMeasureParseTreeAction::ExecuteAction() {
   // Parse. In case of failure, report and return.
   ci.parsing().Parse(llvm::outs());
 
-  if (ci.parsing().messages().AnyFatalError()) {
+  if (!ci.parsing().messages().empty() &&
+      (ci.invocation().warnAsErr() ||
+          ci.parsing().messages().AnyFatalError())) {
     unsigned diagID = ci.diagnostics().getCustomDiagID(
         clang::DiagnosticsEngine::Error, "Could not parse %0");
     ci.diagnostics().Report(diagID) << GetCurrentFileOrBufferName();
index e8b1141..263dfb1 100644 (file)
@@ -51,6 +51,7 @@
 ! CHECK-NEXT: -std=<value>           Language standard to compile for
 ! CHECK-NEXT: -U <macro>             Undefine macro <macro>
 ! CHECK-NEXT: --version Print version information
+! CHECK-NEXT: -W<warning>            Enable the specified warning
 ! CHECK-NEXT: -Xflang <arg>          Pass <arg> to the flang compiler
 
 !-------------------------------------------------------------
index 855d6f2..ba755ef 100644 (file)
@@ -51,6 +51,7 @@
 ! HELP-NEXT: -std=<value>           Language standard to compile for
 ! HELP-NEXT: -U <macro>             Undefine macro <macro>
 ! HELP-NEXT: --version              Print version information
+! HELP-NEXT: -W<warning>            Enable the specified warning
 ! HELP-NEXT: -Xflang <arg>          Pass <arg> to the flang compiler
 
 !-------------------------------------------------------------
 ! HELP-FC1-NEXT: -test-io               Run the InputOuputTest action. Use for development and testing only.
 ! HELP-FC1-NEXT: -U <macro>             Undefine macro <macro>
 ! HELP-FC1-NEXT: --version              Print version information
+! HELP-FC1-NEXT: -W<warning>            Enable the specified warning
 
 !---------------
 ! EXPECTED ERROR
diff --git a/flang/test/Driver/werror_parse.f b/flang/test/Driver/werror_parse.f
new file mode 100644 (file)
index 0000000..f5425f5
--- /dev/null
@@ -0,0 +1,33 @@
+! Ensure argument -Werror work as expected, this file checks for the functional correctness for
+! actions that extend the PrescanAndSemaAction, particularly for Semantic warnings/errors.
+! Multiple RUN lines are added to make sure that the behavior is consistent across multiple actions.
+
+! RUN: not %flang_fc1 -fsyntax-only -std=f2018 -Werror %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -std=f2018 -Werror -fdebug-dump-parse-tree %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -std=f2018 -Werror -fdebug-unparse-with-symbols %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -std=f2018 -Werror -fdebug-unparse %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -std=f2018 -Werror -fdebug-dump-symbols %s  2>&1 | FileCheck %s --check-prefix=WITH
+
+
+! RUN: %flang_fc1 -fsyntax-only -std=f2018 %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -std=f2018 -fdebug-dump-parse-tree %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -std=f2018 -fdebug-unparse-with-symbols %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -std=f2018 -fdebug-unparse %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -std=f2018 -fdebug-dump-symbols %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+
+!-----------------------------------------
+! EXPECTED OUTPUT WITH -Werror
+!-----------------------------------------
+! WITH: Could not parse
+
+!-----------------------------------------
+! EXPECTED OUTPUT WITHOUT -Werror
+!-----------------------------------------
+! WITHOUT-NOT: Could not parse
+
+#ifndef _OM_NO_IOSTREAM
+#ifdef WIN32
+#ifndef USE_IOSTREAM
+#define USE_IOSTREAM
+#endif USE_IOSTREAM
+#endif WIN32
diff --git a/flang/test/Driver/werror_scan.f b/flang/test/Driver/werror_scan.f
new file mode 100644 (file)
index 0000000..8643635
--- /dev/null
@@ -0,0 +1,25 @@
+! Ensure argument -Werror work as expected, this file checks for the functional correctness for
+! actions that extend the PrescanAction
+! Multiple RUN lines are added to make sure that the behavior is consistent across multiple actions.
+
+! RUN: not %flang_fc1 -fsyntax-only -E -Werror %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -fdebug-dump-parsing-log -Werror %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -fdebug-dump-provenance -Werror %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -fdebug-measure-parse-tree -Werror %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: %flang_fc1 -fsyntax-only -E %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -fdebug-dump-parsing-log %s  2>&1 | FileCheck %s --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -fdebug-dump-provenance %s  2>&1 | FileCheck %s --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -fdebug-measure-parse-tree %s  2>&1 | FileCheck %s --check-prefix=WITHOUT
+
+!-----------------------------------------
+! EXPECTED OUTPUT WITH -Werror
+!-----------------------------------------
+! WITH: Could not scan
+
+!-----------------------------------------
+! EXPECTED OUTPUT WITHOUT -Werror
+!-----------------------------------------
+! WITHOUT-NOT: Could not scan
+
+1 continue
+end
diff --git a/flang/test/Driver/werror_sema.f90 b/flang/test/Driver/werror_sema.f90
new file mode 100644 (file)
index 0000000..1a7b6cc
--- /dev/null
@@ -0,0 +1,31 @@
+! Ensure argument -Werror work as expected, this file checks for the functional correctness for
+! actions that extend the PrescanAndSemaAction, particularly for Semantic warnings/errors.
+! Multiple RUN lines are added to make sure that the behavior is consistent across multiple actions.
+
+! RUN: not %flang_fc1 -fsyntax-only -Werror %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -Werror -fdebug-dump-parse-tree %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -Werror -fdebug-unparse-with-symbols %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -Werror -fdebug-unparse %s  2>&1 | FileCheck %s --check-prefix=WITH
+! RUN: not %flang_fc1 -fsyntax-only -Werror -fdebug-dump-symbols %s  2>&1 | FileCheck %s --check-prefix=WITH
+
+
+! RUN: %flang_fc1 -fsyntax-only %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -fdebug-dump-parse-tree %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -fdebug-unparse-with-symbols %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -fdebug-unparse %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+! RUN: %flang_fc1 -fsyntax-only -fdebug-dump-symbols %s  2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
+
+!-----------------------------------------
+! EXPECTED OUTPUT WITH -Werror
+!-----------------------------------------
+! WITH: Semantic errors in
+
+!-----------------------------------------
+! EXPECTED OUTPUT WITHOUT -Werror
+!-----------------------------------------
+! WITHOUT-NOT: Semantic errors in
+
+PROGRAM werror
+REAL, DIMENSION(20, 10) :: A
+FORALL (J=1:N)  A(I, I) = 1
+END PROGRAM werror
diff --git a/flang/test/Driver/werror_wrong.f90 b/flang/test/Driver/werror_wrong.f90
new file mode 100644 (file)
index 0000000..3151bb1
--- /dev/null
@@ -0,0 +1,9 @@
+! Ensure that only argument -Werror is supported.
+
+! RUN: not %flang_fc1 -fsyntax-only -Wall %s  2>&1 | FileCheck %s --check-prefix=WRONG
+! RUN: not %flang_fc1 -fsyntax-only -WX %s  2>&1 | FileCheck %s --check-prefix=WRONG
+
+!-----------------------------------------
+! EXPECTED OUTPUT WITH -W<opt>
+!-----------------------------------------
+! WRONG: Only `-Werror` is supported currently.
index 9c5e6c9..92d04dd 100644 (file)
@@ -511,8 +511,14 @@ int main(int argc, char *const argv[]) {
     } else if (arg == "-fopenmp") {
       options.features.Enable(Fortran::common::LanguageFeature::OpenMP);
       predefinitions.emplace_back("_OPENMP", "201511");
-    } else if (arg == "-Werror") {
-      driver.warningsAreErrors = true;
+    } else if (arg.find("-W") != std::string::npos) {
+      if (arg == "-Werror")
+        driver.warningsAreErrors = true;
+      else {
+        // Only -Werror is supported currently
+        llvm::errs() << "Only `-Werror` is supported currently.\n";
+        return EXIT_FAILURE;
+      }
     } else if (arg == "-ed") {
       options.features.Enable(Fortran::common::LanguageFeature::OldDebugLines);
     } else if (arg == "-E") {