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
{
- severity_disabled = 0,
- severity_unset = 1,
- severity_warning = 2,
- severity_error = 3,
- severity_fatal = 4
+ severity_disabled = 0, /**< Explicitly disabled via -Wno-foo. */
+ severity_unset = 1, /**< Unspecified status. */
+ severity_warning = 2, /**< A warning. */
+ severity_error = 3, /**< An error (continue, but die soon). */
+ severity_fatal = 4 /**< Fatal error (die now). */
} severity;
"conflicts-sr",
"conflicts-rr",
"deprecated",
+ "empty-rule",
"precedence",
"other",
"all",
"error",
+ "everything",
0
};
Wconflicts_sr,
Wconflicts_rr,
Wdeprecated,
+ Wempty_rule,
Wprecedence,
Wother,
Wall,
- Werror
+ Werror,
+ Weverything
};
ARGMATCH_VERIFY (warnings_args, warnings_types);
int value = XARGMATCH ("--warning", arg + no + err,
warnings_args, warnings_types);
- /* -Wnone == -Wno-all, and -Wno-none == -Wall. */
+ /* -Wnone == -Wno-everything, and -Wno-none == -Weverything. */
if (!value)
{
- value = Wall;
+ value = Weverything;
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.
if (STREQ (args, "error"))
warnings_are_errors = true;
else if (STREQ (args, "no-error"))
- {
- warnings_are_errors = false;
- warning_argmatch ("no-error=all", 3, 6);
- }
+ warnings_are_errors = false;
else
{
+ // The length of the possible 'no-' prefix: 3, or 0.
size_t no = STRPREFIX_LIT ("no-", args) ? 3 : 0;
+ // The length of the possible 'error=' (possibly after
+ // 'no-') prefix: 6, or 0.
size_t err = STRPREFIX_LIT ("error=", args + no) ? 6 : 0;
warning_argmatch (args, no, err);
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;
}
}
+bool
+warning_is_unset (warnings flags)
+{
+ size_t b;
+ for (b = 0; b < warnings_size; ++b)
+ if (flags & 1 << b && warnings_flag[b] != severity_unset)
+ return false;
+ return true;
+}
/** Display a "[-Wyacc]" like message on \a f. */
_("deprecated directive: %s, use %s"),
quote (old), quote_n (1, upd));
}
+
+void
+duplicate_directive (char const *directive,
+ location first, location second)
+{
+ unsigned i = 0;
+ complain (&second, complaint, _("only one %s allowed per rule"), directive);
+ i += SUB_INDENT;
+ complain_indent (&first, complaint, &i, _("previous declaration"));
+}