mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
diagnostics: complain about undeclared string tokens
String literals, which allow for better error messages, are (too)
liberally accepted by Bison, which might result in silent errors. For
instance
%type <exVal> cond "condition"
does not define “condition” as a string alias to 'cond' (nonterminal
symbols do not have string aliases). It is rather equivalent to
%nterm <exVal> cond
%token <exVal> "condition"
i.e., it gives the type 'exVal' to the "condition" token, which was
clearly not the intention.
Introduce -Wdangling-alias to catch this.
* src/complain.h, src/complain.c: Add support for -Wdangling-alias.
(argmatch_warning_args): Sort.
* src/symtab.c (symbol_check_defined): Complain about dangling
aliases.
* doc/bison.texi: Document it.
* tests/input.at (Dangling aliases): New test.
This commit is contained in:
38
NEWS
38
NEWS
@@ -4,6 +4,44 @@ GNU Bison NEWS
|
||||
|
||||
** New Features
|
||||
|
||||
*** New diagnostic: -Wdangling-alias
|
||||
|
||||
String literals, which allow for better error messages, are (too)
|
||||
liberally accepted by Bison, which might result in silent errors. For
|
||||
instance
|
||||
|
||||
%type <exVal> cond "condition"
|
||||
|
||||
does not define "condition" as a string alias to 'cond' (nonterminal
|
||||
symbols do not have string aliases). It is rather equivalent to
|
||||
|
||||
%nterm <exVal> cond
|
||||
%token <exVal> "condition"
|
||||
|
||||
i.e., it gives the type 'exVal' to the "condition" token, which was
|
||||
clearly not the intention.
|
||||
|
||||
Also, because string aliases need not be defined, typos such as "baz"
|
||||
instead of "bar" will be not reported.
|
||||
|
||||
The option -Wdangling-alias catches these situations. On
|
||||
|
||||
%token BAR "bar"
|
||||
%type <ival> foo "foo"
|
||||
%%
|
||||
foo: "baz" {}
|
||||
|
||||
bison -Wdangling-alias reports
|
||||
|
||||
warning: string literal not attached to a symbol
|
||||
| %type <ival> foo "foo"
|
||||
| ^~~~~
|
||||
warning: string literal not attached to a symbol
|
||||
| foo: "baz" {}
|
||||
| ^~~~~
|
||||
|
||||
The -Wall option does not (yet?) include -Wdangling-alias.
|
||||
|
||||
*** Better POSIX Yacc compatibility diagnostics
|
||||
|
||||
POSIX Yacc restricts %type to nonterminals. This is now diagnosed by
|
||||
|
||||
@@ -3551,8 +3551,9 @@ They are still considered distinct rules even when joined in this way.
|
||||
@findex %empty
|
||||
|
||||
A rule is said to be @dfn{empty} if its right-hand side (@var{components})
|
||||
is empty. It means that @var{result} can match the empty string. For
|
||||
example, here is how to define an optional semicolon:
|
||||
is empty. It means that @var{result} in the previous example can match the
|
||||
empty string. As another example, here is how to define an optional
|
||||
semicolon:
|
||||
|
||||
@example
|
||||
semicolon.opt: | ";";
|
||||
@@ -10531,6 +10532,52 @@ unexpected number of conflicts is an error, and an expected number of
|
||||
conflicts is not reported, so @option{-W} and @option{--warning} then have
|
||||
no effect on the conflict report.
|
||||
|
||||
@item dangling-alias
|
||||
Report string literals that are not bound to a token symbol.
|
||||
|
||||
String literals, which allow for better error messages, are (too) liberally
|
||||
accepted by Bison, which might result in silent errors. For instance
|
||||
|
||||
@example
|
||||
%type <exVal> cond "condition"
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
does not define ``condition'' as a string alias to @code{cond}---nonterminal
|
||||
symbols do not have string aliases. It is rather equivalent to
|
||||
|
||||
@example
|
||||
%nterm <exVal> cond
|
||||
%token <exVal> "condition"
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
i.e., it gives the @samp{"condition"} token the type @code{exVal}.
|
||||
|
||||
Also, because string aliases do not need to be defined, typos such as
|
||||
@samp{"baz"} instead of @samp{"bar"} will be not reported.
|
||||
|
||||
The option @option{-Wdangling-alias} catches these situations. On
|
||||
|
||||
@example
|
||||
%token BAR "bar"
|
||||
%type <ival> foo "foo"
|
||||
%%
|
||||
foo: "baz" @{@}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@command{bison -Wdangling-alias} reports
|
||||
|
||||
@example
|
||||
@dwarning{warning}: string literal not attached to a symbol
|
||||
| %type <ival> foo @dwarning{"foo"}
|
||||
| @dwarning{^~~~~}
|
||||
@dwarning{warning}: string literal not attached to a symbol
|
||||
| foo: @dwarning{"baz"} @{@}
|
||||
| @dwarning{^~~~~}
|
||||
@end example
|
||||
|
||||
@item deprecated
|
||||
Deprecated constructs whose support will be removed in future versions of
|
||||
Bison.
|
||||
@@ -10632,7 +10679,7 @@ releases of Bison may move warnings from this category to new, more specific
|
||||
categories.
|
||||
|
||||
@item all
|
||||
All the warnings except @code{yacc}.
|
||||
All the warnings except @code{dangling-alias} and @code{yacc}.
|
||||
|
||||
@item none
|
||||
Turn off all the warnings.
|
||||
|
||||
@@ -113,13 +113,14 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
|
||||
{
|
||||
{ "conflicts-sr", N_("S/R conflicts (enabled by default)") },
|
||||
{ "conflicts-rr", N_("R/R conflicts (enabled by default)") },
|
||||
{ "dangling-alias", N_("string aliases not attached to a symbol") },
|
||||
{ "deprecated", N_("obsolete constructs") },
|
||||
{ "empty-rule", N_("empty rules without %empty") },
|
||||
{ "midrule-values", N_("unset or unused midrule values") },
|
||||
{ "precedence", N_("useless precedence and associativity") },
|
||||
{ "yacc", N_("incompatibilities with POSIX Yacc") },
|
||||
{ "other", N_("all other warnings (enabled by default)") },
|
||||
{ "all", N_("all the warnings except 'yacc'") },
|
||||
{ "all", N_("all the warnings except 'dangling-alias' and 'yacc'") },
|
||||
{ "no-CATEGORY", N_("turn off warnings in CATEGORY") },
|
||||
{ "none", N_("turn off all the warnings") },
|
||||
{ "error[=CATEGORY]", N_("treat warnings as errors") },
|
||||
@@ -128,17 +129,18 @@ static const argmatch_warning_doc argmatch_warning_docs[] =
|
||||
|
||||
static const argmatch_warning_arg argmatch_warning_args[] =
|
||||
{
|
||||
{ "none", Wnone },
|
||||
{ "midrule-values", Wmidrule_values },
|
||||
{ "yacc", Wyacc },
|
||||
{ "conflicts-sr", Wconflicts_sr },
|
||||
{ "all", Wall },
|
||||
{ "conflicts-rr", Wconflicts_rr },
|
||||
{ "conflicts-sr", Wconflicts_sr },
|
||||
{ "dangling-alias", Wdangling_alias },
|
||||
{ "deprecated", Wdeprecated },
|
||||
{ "empty-rule", Wempty_rule },
|
||||
{ "precedence", Wprecedence },
|
||||
{ "other", Wother },
|
||||
{ "all", Wall },
|
||||
{ "everything", Weverything },
|
||||
{ "midrule-values", Wmidrule_values },
|
||||
{ "none", Wnone },
|
||||
{ "other", Wother },
|
||||
{ "precedence", Wprecedence },
|
||||
{ "yacc", Wyacc },
|
||||
{ NULL, Wnone }
|
||||
};
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ typedef enum
|
||||
{
|
||||
warning_conflicts_rr,
|
||||
warning_conflicts_sr,
|
||||
warning_dangling_alias,
|
||||
warning_deprecated,
|
||||
warning_empty_rule,
|
||||
warning_midrule_values,
|
||||
@@ -104,6 +105,7 @@ typedef enum
|
||||
|
||||
Wconflicts_rr = 1 << warning_conflicts_rr,
|
||||
Wconflicts_sr = 1 << warning_conflicts_sr,
|
||||
Wdangling_alias = 1 << warning_dangling_alias,
|
||||
Wdeprecated = 1 << warning_deprecated,
|
||||
Wempty_rule = 1 << warning_empty_rule,
|
||||
Wmidrule_values = 1 << warning_midrule_values,
|
||||
@@ -118,7 +120,7 @@ typedef enum
|
||||
|
||||
/**< All above warnings. */
|
||||
Weverything = ~complaint & ~fatal & ~silent,
|
||||
Wall = Weverything & ~Wyacc
|
||||
Wall = Weverything & ~Wdangling_alias & ~Wyacc
|
||||
} warnings;
|
||||
|
||||
/** Whether the warnings of \a flags are all unset.
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
#include <assure.h>
|
||||
#include <fstrcmp.h>
|
||||
#include <hash.h>
|
||||
#include <quote.h>
|
||||
|
||||
#include "complain.h"
|
||||
#include "getargs.h"
|
||||
#include "gram.h"
|
||||
#include "intprops.h"
|
||||
#include "quote.h"
|
||||
|
||||
static struct hash_table *symbol_table = NULL;
|
||||
static struct hash_table *semantic_type_table = NULL;
|
||||
@@ -610,6 +610,13 @@ symbol_check_defined (symbol *sym)
|
||||
s->number = nvars++;
|
||||
}
|
||||
|
||||
if (s->class == token_sym
|
||||
&& sym->tag[0] == '"'
|
||||
&& !sym->is_alias)
|
||||
complain (&sym->location, Wdangling_alias,
|
||||
_("string literal %s not attached to a symbol"),
|
||||
sym->tag);
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
symbol_code_props_get (sym, i)->is_used = true;
|
||||
|
||||
|
||||
@@ -298,6 +298,31 @@ input.y:8.14: error: syntax error, unexpected integer
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## ------------------ ##
|
||||
## Dangling aliases. ##
|
||||
## ------------------ ##
|
||||
|
||||
AT_SETUP([Dangling aliases])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%token FOO "foo"
|
||||
%type <val> "bar"
|
||||
%%
|
||||
expr: "foo" "bar" "baz"
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret -Wdangling input.y], [0], [],
|
||||
[[input.y:2.13-17: warning: string literal "bar" not attached to a symbol [-Wdangling-alias]
|
||||
2 | %type <val> "bar"
|
||||
| ^~~~~
|
||||
input.y:4.19-23: warning: string literal "baz" not attached to a symbol [-Wdangling-alias]
|
||||
4 | expr: "foo" "bar" "baz"
|
||||
| ^~~~~
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
## --------------------- ##
|
||||
## Symbol declarations. ##
|
||||
## --------------------- ##
|
||||
|
||||
Reference in New Issue
Block a user