[Diagnostics] -suppress-warnings and -warnings-as-errors flags

Exposes the global warning suppression and treatment as errors
functionality to the Swift driver. Introduces the flags
"-suppress-warnings" and "-warnings-as-errors". Test case include.
This commit is contained in:
Michael Ilseman
2016-01-13 18:38:26 -08:00
parent 8b5fb7d200
commit dc689e607c
10 changed files with 70 additions and 7 deletions

View File

@@ -399,7 +399,7 @@ namespace swift {
bool showDiagnosticsAfterFatalError = false; bool showDiagnosticsAfterFatalError = false;
/// \brief Don't emit any warnings /// \brief Don't emit any warnings
bool ignoreAllWarnings = false; bool suppressWarnings = false;
/// \brief Emit all warnings as errors /// \brief Emit all warnings as errors
bool warningsAsErrors = false; bool warningsAsErrors = false;
@@ -431,8 +431,8 @@ namespace swift {
} }
/// \brief Whether to skip emitting warnings /// \brief Whether to skip emitting warnings
void setIgnoreAllWarnings(bool val) { ignoreAllWarnings = val; } void setSuppressWarnings(bool val) { suppressWarnings = val; }
bool getIgnoreAllWarnings() const { return ignoreAllWarnings; } bool getSuppressWarnings() const { return suppressWarnings; }
/// \brief Whether to treat warnings as errors /// \brief Whether to treat warnings as errors
void setWarningsAsErrors(bool val) { warningsAsErrors = val; } void setWarningsAsErrors(bool val) { warningsAsErrors = val; }
@@ -506,9 +506,9 @@ namespace swift {
} }
/// \brief Whether to skip emitting warnings /// \brief Whether to skip emitting warnings
void setIgnoreAllWarnings(bool val) { state.setIgnoreAllWarnings(val); } void setSuppressWarnings(bool val) { state.setSuppressWarnings(val); }
bool getIgnoreAllWarnings() const { bool getSuppressWarnings() const {
return state.getIgnoreAllWarnings(); return state.getSuppressWarnings();
} }
/// \brief Whether to treat warnings as errors /// \brief Whether to treat warnings as errors

View File

@@ -115,6 +115,10 @@ ERROR(error_input_changed_during_build,none,
"input file '%0' was modified during the build", "input file '%0' was modified during the build",
(StringRef)) (StringRef))
ERROR(error_conflicting_options, none,
"conflicting options '%0' and '%1'",
(StringRef, StringRef))
#ifndef DIAG_NO_UNDEF #ifndef DIAG_NO_UNDEF
# if defined(DIAG) # if defined(DIAG)
# undef DIAG # undef DIAG

View File

@@ -35,6 +35,12 @@ public:
/// When emitting fixits as code edits, apply all fixits from diagnostics /// When emitting fixits as code edits, apply all fixits from diagnostics
/// without any filtering. /// without any filtering.
bool FixitCodeForAllDiagnostics = false; bool FixitCodeForAllDiagnostics = false;
/// Suppress all warnings
bool SuppressWarnings = false;
/// Treat all warnings as errors
bool WarningsAsErrors = false;
}; };
} }

View File

@@ -218,6 +218,15 @@ def solver_memory_threshold : Separate<["-"], "solver-memory-threshold">,
Flags<[FrontendOption, HelpHidden, DoesNotAffectIncrementalBuild]>, Flags<[FrontendOption, HelpHidden, DoesNotAffectIncrementalBuild]>,
HelpText<"Set the upper bound for memory consumption, in bytes, by the constraint solver">; HelpText<"Set the upper bound for memory consumption, in bytes, by the constraint solver">;
// Diagnostic control options
def suppress_warnings : Flag<["-"], "suppress-warnings">,
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
HelpText<"Suppress all warnings">;
def warnings_as_errors : Flag<["-"], "warnings-as-errors">,
Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>,
HelpText<"Treat warnings as errors">;
// Platform options. // Platform options.
def enable_app_extension : Flag<["-"], "application-extension">, def enable_app_extension : Flag<["-"], "application-extension">,
Flags<[FrontendOption, NoInteractiveOption]>, Flags<[FrontendOption, NoInteractiveOption]>,

View File

@@ -528,7 +528,7 @@ DiagnosticState::Behavior DiagnosticState::determineBehavior(DiagID id) {
// 3) If the user provided a behavior for this diagnostic's kind, follow // 3) If the user provided a behavior for this diagnostic's kind, follow
// that // that
if (diagInfo.kind == DiagnosticKind::Warning) { if (diagInfo.kind == DiagnosticKind::Warning) {
if (ignoreAllWarnings) if (suppressWarnings)
return set(Behavior::Ignore); return set(Behavior::Ignore);
if (warningsAsErrors) if (warningsAsErrors)
return set(Behavior::Error); return set(Behavior::Error);

View File

@@ -147,6 +147,13 @@ static void validateArgs(DiagnosticEngine &diags, const ArgList &Args) {
} }
} }
} }
// Check for conflicting warning control flags
if (Args.hasArg(options::OPT_suppress_warnings) &&
Args.hasArg(options::OPT_warnings_as_errors)) {
diags.diagnose(SourceLoc(), diag::error_conflicting_options,
"-warnings-as-errors", "-suppress-warnings");
}
} }
static void computeArgsHash(SmallString<32> &out, const DerivedArgList &args) { static void computeArgsHash(SmallString<32> &out, const DerivedArgList &args) {

View File

@@ -126,8 +126,10 @@ static void addCommonFrontendArgs(const ToolChain &TC,
inputArgs.AddLastArg(arguments, options::OPT_parse_stdlib); inputArgs.AddLastArg(arguments, options::OPT_parse_stdlib);
inputArgs.AddLastArg(arguments, options::OPT_resource_dir); inputArgs.AddLastArg(arguments, options::OPT_resource_dir);
inputArgs.AddLastArg(arguments, options::OPT_solver_memory_threshold); inputArgs.AddLastArg(arguments, options::OPT_solver_memory_threshold);
inputArgs.AddLastArg(arguments, options::OPT_suppress_warnings);
inputArgs.AddLastArg(arguments, options::OPT_profile_generate); inputArgs.AddLastArg(arguments, options::OPT_profile_generate);
inputArgs.AddLastArg(arguments, options::OPT_profile_coverage_mapping); inputArgs.AddLastArg(arguments, options::OPT_profile_coverage_mapping);
inputArgs.AddLastArg(arguments, options::OPT_warnings_as_errors);
// Pass on any build config options // Pass on any build config options
inputArgs.AddAllArgs(arguments, options::OPT_D); inputArgs.AddAllArgs(arguments, options::OPT_D);

View File

@@ -922,6 +922,11 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Args.hasArg(OPT_show_diagnostics_after_fatal); Args.hasArg(OPT_show_diagnostics_after_fatal);
Opts.UseColor |= Args.hasArg(OPT_color_diagnostics); Opts.UseColor |= Args.hasArg(OPT_color_diagnostics);
Opts.FixitCodeForAllDiagnostics |= Args.hasArg(OPT_fixit_all); Opts.FixitCodeForAllDiagnostics |= Args.hasArg(OPT_fixit_all);
Opts.SuppressWarnings |= Args.hasArg(OPT_suppress_warnings);
Opts.WarningsAsErrors |= Args.hasArg(OPT_warnings_as_errors);
assert(!(Opts.WarningsAsErrors && Opts.SuppressWarnings) &&
"conflicting arguments; should of been caught by driver");
return false; return false;
} }

View File

@@ -69,6 +69,12 @@ bool CompilerInstance::setup(const CompilerInvocation &Invok) {
if (Invocation.getDiagnosticOptions().ShowDiagnosticsAfterFatalError) { if (Invocation.getDiagnosticOptions().ShowDiagnosticsAfterFatalError) {
Diagnostics.setShowDiagnosticsAfterFatalError(); Diagnostics.setShowDiagnosticsAfterFatalError();
} }
if (Invocation.getDiagnosticOptions().SuppressWarnings) {
Diagnostics.setSuppressWarnings(true);
}
if (Invocation.getDiagnosticOptions().WarningsAsErrors) {
Diagnostics.setWarningsAsErrors(true);
}
// If we are asked to emit a module documentation file, configure lexing and // If we are asked to emit a module documentation file, configure lexing and
// parsing to remember comments. // parsing to remember comments.

View File

@@ -0,0 +1,24 @@
// RUN: not %target-swiftc_driver %s 2>&1 | FileCheck -check-prefix=DEFAULT %s
// RUN: not %target-swiftc_driver -warnings-as-errors %s 2>&1 | FileCheck -check-prefix=WERR %s
// RUN: not %target-swiftc_driver -suppress-warnings %s 2>&1 | FileCheck -check-prefix=NOWARN %s
// RUN: not %target-swiftc_driver -suppress-warnings -warnings-as-errors %s 2>&1 | FileCheck -check-prefix=FLAGS_CONFLICT %s
// FLAGS_CONFLICT: error: conflicting options '-warnings-as-errors' and '-suppress-warnings'
func foo() -> Int {
let x = 1
var y = 2
// DEFAULT: warning: variable 'y' was never mutated; consider changing to 'let' constant
// WERR: error: variable 'y' was never mutated; consider changing to 'let' constant
// NOWARN-NOT: variable 'y' was never mutated
return x + y
}
func bar() {
foo()
// To help anchor the checks, have an error. Put it inside a later function, to help make sure it comes after
xyz
// DEFAULT: error: use of unresolved identifier 'xyz'
// WERR: error: use of unresolved identifier 'xyz'
// NOWARN: error: use of unresolved identifier 'xyz'
}