mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +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 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
|
*** Better POSIX Yacc compatibility diagnostics
|
||||||
|
|
||||||
POSIX Yacc restricts %type to nonterminals. This is now diagnosed by
|
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
|
@findex %empty
|
||||||
|
|
||||||
A rule is said to be @dfn{empty} if its right-hand side (@var{components})
|
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
|
is empty. It means that @var{result} in the previous example can match the
|
||||||
example, here is how to define an optional semicolon:
|
empty string. As another example, here is how to define an optional
|
||||||
|
semicolon:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
semicolon.opt: | ";";
|
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
|
conflicts is not reported, so @option{-W} and @option{--warning} then have
|
||||||
no effect on the conflict report.
|
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
|
@item deprecated
|
||||||
Deprecated constructs whose support will be removed in future versions of
|
Deprecated constructs whose support will be removed in future versions of
|
||||||
Bison.
|
Bison.
|
||||||
@@ -10632,7 +10679,7 @@ releases of Bison may move warnings from this category to new, more specific
|
|||||||
categories.
|
categories.
|
||||||
|
|
||||||
@item all
|
@item all
|
||||||
All the warnings except @code{yacc}.
|
All the warnings except @code{dangling-alias} and @code{yacc}.
|
||||||
|
|
||||||
@item none
|
@item none
|
||||||
Turn off all the warnings.
|
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-sr", N_("S/R conflicts (enabled by default)") },
|
||||||
{ "conflicts-rr", N_("R/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") },
|
{ "deprecated", N_("obsolete constructs") },
|
||||||
{ "empty-rule", N_("empty rules without %empty") },
|
{ "empty-rule", N_("empty rules without %empty") },
|
||||||
{ "midrule-values", N_("unset or unused midrule values") },
|
{ "midrule-values", N_("unset or unused midrule values") },
|
||||||
{ "precedence", N_("useless precedence and associativity") },
|
{ "precedence", N_("useless precedence and associativity") },
|
||||||
{ "yacc", N_("incompatibilities with POSIX Yacc") },
|
{ "yacc", N_("incompatibilities with POSIX Yacc") },
|
||||||
{ "other", N_("all other warnings (enabled by default)") },
|
{ "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") },
|
{ "no-CATEGORY", N_("turn off warnings in CATEGORY") },
|
||||||
{ "none", N_("turn off all the warnings") },
|
{ "none", N_("turn off all the warnings") },
|
||||||
{ "error[=CATEGORY]", N_("treat warnings as errors") },
|
{ "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[] =
|
static const argmatch_warning_arg argmatch_warning_args[] =
|
||||||
{
|
{
|
||||||
{ "none", Wnone },
|
{ "all", Wall },
|
||||||
{ "midrule-values", Wmidrule_values },
|
|
||||||
{ "yacc", Wyacc },
|
|
||||||
{ "conflicts-sr", Wconflicts_sr },
|
|
||||||
{ "conflicts-rr", Wconflicts_rr },
|
{ "conflicts-rr", Wconflicts_rr },
|
||||||
|
{ "conflicts-sr", Wconflicts_sr },
|
||||||
|
{ "dangling-alias", Wdangling_alias },
|
||||||
{ "deprecated", Wdeprecated },
|
{ "deprecated", Wdeprecated },
|
||||||
{ "empty-rule", Wempty_rule },
|
{ "empty-rule", Wempty_rule },
|
||||||
{ "precedence", Wprecedence },
|
|
||||||
{ "other", Wother },
|
|
||||||
{ "all", Wall },
|
|
||||||
{ "everything", Weverything },
|
{ "everything", Weverything },
|
||||||
|
{ "midrule-values", Wmidrule_values },
|
||||||
|
{ "none", Wnone },
|
||||||
|
{ "other", Wother },
|
||||||
|
{ "precedence", Wprecedence },
|
||||||
|
{ "yacc", Wyacc },
|
||||||
{ NULL, Wnone }
|
{ NULL, Wnone }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ typedef enum
|
|||||||
{
|
{
|
||||||
warning_conflicts_rr,
|
warning_conflicts_rr,
|
||||||
warning_conflicts_sr,
|
warning_conflicts_sr,
|
||||||
|
warning_dangling_alias,
|
||||||
warning_deprecated,
|
warning_deprecated,
|
||||||
warning_empty_rule,
|
warning_empty_rule,
|
||||||
warning_midrule_values,
|
warning_midrule_values,
|
||||||
@@ -104,6 +105,7 @@ typedef enum
|
|||||||
|
|
||||||
Wconflicts_rr = 1 << warning_conflicts_rr,
|
Wconflicts_rr = 1 << warning_conflicts_rr,
|
||||||
Wconflicts_sr = 1 << warning_conflicts_sr,
|
Wconflicts_sr = 1 << warning_conflicts_sr,
|
||||||
|
Wdangling_alias = 1 << warning_dangling_alias,
|
||||||
Wdeprecated = 1 << warning_deprecated,
|
Wdeprecated = 1 << warning_deprecated,
|
||||||
Wempty_rule = 1 << warning_empty_rule,
|
Wempty_rule = 1 << warning_empty_rule,
|
||||||
Wmidrule_values = 1 << warning_midrule_values,
|
Wmidrule_values = 1 << warning_midrule_values,
|
||||||
@@ -118,7 +120,7 @@ typedef enum
|
|||||||
|
|
||||||
/**< All above warnings. */
|
/**< All above warnings. */
|
||||||
Weverything = ~complaint & ~fatal & ~silent,
|
Weverything = ~complaint & ~fatal & ~silent,
|
||||||
Wall = Weverything & ~Wyacc
|
Wall = Weverything & ~Wdangling_alias & ~Wyacc
|
||||||
} warnings;
|
} warnings;
|
||||||
|
|
||||||
/** Whether the warnings of \a flags are all unset.
|
/** Whether the warnings of \a flags are all unset.
|
||||||
|
|||||||
@@ -26,12 +26,12 @@
|
|||||||
#include <assure.h>
|
#include <assure.h>
|
||||||
#include <fstrcmp.h>
|
#include <fstrcmp.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
|
#include <quote.h>
|
||||||
|
|
||||||
#include "complain.h"
|
#include "complain.h"
|
||||||
#include "getargs.h"
|
#include "getargs.h"
|
||||||
#include "gram.h"
|
#include "gram.h"
|
||||||
#include "intprops.h"
|
#include "intprops.h"
|
||||||
#include "quote.h"
|
|
||||||
|
|
||||||
static struct hash_table *symbol_table = NULL;
|
static struct hash_table *symbol_table = NULL;
|
||||||
static struct hash_table *semantic_type_table = NULL;
|
static struct hash_table *semantic_type_table = NULL;
|
||||||
@@ -610,6 +610,13 @@ symbol_check_defined (symbol *sym)
|
|||||||
s->number = nvars++;
|
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)
|
for (int i = 0; i < 2; ++i)
|
||||||
symbol_code_props_get (sym, i)->is_used = true;
|
symbol_code_props_get (sym, i)->is_used = true;
|
||||||
|
|
||||||
|
|||||||
@@ -298,6 +298,31 @@ input.y:8.14: error: syntax error, unexpected integer
|
|||||||
AT_CLEANUP
|
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. ##
|
## Symbol declarations. ##
|
||||||
## --------------------- ##
|
## --------------------- ##
|
||||||
|
|||||||
Reference in New Issue
Block a user