diagnostics: "-Werror -Wno-error=foo" must not emit errors

Currently "-Werror -Wno-error=foo" still turns "foo" warnings into errors.
Reported by Alexandre Duret-Lutz.
See http://lists.gnu.org/archive/html/bug-bison/2013-09/msg00015.html.

* src/complain.c (errority, errority_flag): New.
(complain_init): Initialize the latter.
(warning_argmatch): Extract the loop iterating on the flag's bits.
Set and unset errority_flag here.
(warnings_argmatch): -Wno-error is not the same as -Wno-error=everything:
we must remember if category foo was explicitly turned in an error/warning
via -W(no-)error=foo.
(warning_severity): Use errority_flag.

* tests/input.at (Symbols): Just check --yacc, not -Wyacc, that's the
job of tests on -W.
(-Werror is not affected by -Wnone and -Wall): Rename as...
(-Werror combinations): this.
Tests more combinations of -W, -W(no-)error, and -W(no-)error=foo.
* tests/local.at (AT_BISON_CHECK_WARNINGS): Don't expect -Werror
to turn runs that issue warnings into runs with errors, as the
warnings might be enforced as warnings by -Wno-error=foo, in which
case -Werror does not change anything.

* doc/bison.texi (Bison Options): Try to be clearer about how
-W(no-)error and -W(no-)error=foo interact.
This commit is contained in:
Akim Demaille
2013-10-16 10:55:28 +02:00
parent 2b7fe38c36
commit e4678430c2
5 changed files with 102 additions and 57 deletions

View File

@@ -35,6 +35,17 @@ err_status complaint_status = status_none;
bool warnings_are_errors = false;
/** Whether -Werror/-Wno-error was applied to a warning. */
typedef enum
{
errority_unset = 0, /** No explict status. */
errority_disabled = 1, /** Explictly disabled with -Wno-error=foo. */
errority_enabled = 2 /** Explictly enabled with -Werror=foo. */
} errority;
/** For each warning type, its errority. */
static errority errority_flag[warnings_size];
/** Diagnostics severity. */
typedef enum
{
@@ -103,32 +114,26 @@ warning_argmatch (char const *arg, size_t no, size_t err)
no = !no;
}
if (no)
{
size_t b;
for (b = 0; b < warnings_size; ++b)
if (value & 1 << b)
size_t b;
for (b = 0; b < warnings_size; ++b)
if (value & 1 << b)
{
if (err && no)
/* -Wno-error=foo. */
errority_flag[b] = errority_disabled;
else if (err && !no)
{
if (err)
{
/* -Wno-error=foo: if foo enabled as an error,
make it a warning. */
if (warnings_flag[b] == severity_error)
warnings_flag[b] = severity_warning;
}
else
/* -Wno-foo. */
warnings_flag[b] = severity_disabled;
/* -Werror=foo: enables -Wfoo. */
errority_flag[b] = errority_enabled;
warnings_flag[b] = severity_warning;
}
}
else
{
size_t b;
for (b = 0; b < warnings_size; ++b)
if (value & 1 << b)
/* -Wfoo and -Werror=foo. */
warnings_flag[b] = err ? severity_error : severity_warning;
}
else if (no)
/* -Wno-foo. */
warnings_flag[b] = severity_disabled;
else
/* -Wfoo. */
warnings_flag[b] = severity_warning;
}
}
/** Decode a comma-separated list of arguments from -W.
@@ -145,10 +150,7 @@ warnings_argmatch (char *args)
if (STREQ (args, "error"))
warnings_are_errors = true;
else if (STREQ (args, "no-error"))
{
warnings_are_errors = false;
warning_argmatch ("no-error=everything", 3, 6);
}
warnings_are_errors = false;
else
{
// The length of the possible 'no-' prefix: 3, or 0.
@@ -176,27 +178,46 @@ complain_init (void)
size_t b;
for (b = 0; b < warnings_size; ++b)
warnings_flag[b] = (1 << b & warnings_default
? severity_warning
: severity_unset);
{
warnings_flag[b] = (1 << b & warnings_default
? severity_warning
: severity_unset);
errority_flag[b] = errority_unset;
}
}
/* A diagnostic with FLAGS is about to be issued. With what severity?
(severity_fatal, severity_error, severity_disabled, or
severity_warning.) */
static severity
warning_severity (warnings flags)
{
if (flags & fatal)
/* Diagnostics about fatal errors. */
return severity_fatal;
else if (flags & complaint)
/* Diagnostics about errors. */
return severity_error;
else
{
/* Diagnostics about warnings. */
severity res = severity_disabled;
size_t b;
for (b = 0; b < warnings_size; ++b)
if (flags & 1 << b)
res = res < warnings_flag[b] ? warnings_flag[b] : res;
if (res == severity_warning && warnings_are_errors)
res = severity_error;
{
res = res < warnings_flag[b] ? warnings_flag[b] : res;
/* If the diagnostic is enabled, and -Werror is enabled,
and -Wno-error=foo was not explicitly requested, this
is an error. */
if (res == severity_warning
&& (errority_flag[b] == errority_enabled
|| (warnings_are_errors
&& errority_flag[b] != errority_disabled)))
res = severity_error;
}
return res;
}
}