With the option given, warnings are treated as error.
Reviewed By: awarzynski
Differential Revision: https://reviews.llvm.org/D98657
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>">,
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,
bool debugModuleDir_ = false;
+ bool warnAsErr_ = false;
+
// Fortran Dialect options
Fortran::common::IntrinsicTypeDefaultKinds defaultKinds_;
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_;
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
}
}
+/// 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,
parseSemaArgs(res, args, diags);
// Parse dialect arguments
parseDialectArgs(res, args, diags);
+ // Parse diagnostic arguments
+ parseDiagArgs(res, args, diags);
return success;
}
semanticsContext_->set_moduleDirectory(moduleDir())
.set_searchDirectories(fortranOptions.searchDirectories)
- .set_warnOnNonstandardUsage(enableConformanceChecks());
+ .set_warnOnNonstandardUsage(enableConformanceChecks())
+ .set_warningsAreErrors(warnAsErr());
}
// 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();
// 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();
// 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();
// 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();
! 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
!-------------------------------------------------------------
! 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
--- /dev/null
+! 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
--- /dev/null
+! 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
--- /dev/null
+! 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
--- /dev/null
+! 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.
} 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") {