warnings: raise warning for useless printers or destructors

* src/scan-code.h (code_props): Add field 'is_used'.
(CODE_PROPS_NONE_INIT): Adjust.
* src/scan-code.l (code_props_plain_init, code_props_symbol_action_init)
(code_props_rule_action_init): Instead of implementing several
times the initialization of the code_props structures,
use code_props_none_init.
* src/symtab.c (symbol_check_defined): If a symbol does not have a
destructor (resp. printer) but has a type which has a destructor (resp.
printer), then set field 'is_used' to true.
(semantic_type_check_defined): If a type has a destructor (resp. printer)
but all symbols of this type have already a destructor (resp. printer),
then raise a warning.
* tests/input.at (Useless printers or destructors): New.

Signed-off-by: Akim Demaille <akim@lrde.epita.fr>
This commit is contained in:
Victor Santet
2012-06-14 14:20:07 +02:00
committed by Akim Demaille
parent 9641b918ba
commit ea9a35c605
5 changed files with 96 additions and 10 deletions

14
NEWS
View File

@@ -31,6 +31,20 @@ GNU Bison NEWS
This is now only a warning.
** Warnings about useless destructors or printers
Bison now warns about useless destructors or printers. In the following
example, the printer for <type1>, and the destructor for <type2> are
useless: all symbols of <type1> (token1) already have a printer, and all
symbols of type <type2> (token2) already have a destructor.
%token <type1> token1
<type2> token2
<type3> token3
<type4> token4
%printer {} token1 <type1> <type3>
%destructor {} token2 <type2> <type4>
** Additional yylex/yyparse arguments
The new directive %param declares additional arguments to both yylex and

View File

@@ -69,6 +69,10 @@ typedef struct code_props {
*/
bool is_predicate;
/**
* Whether this is actually used (i.e., not completely masked by
* other code props). */
bool is_used;
/** \c NULL iff \c code_props::kind is not \c CODE_PROPS_RULE_ACTION. */
struct symbol_list *rule;
@@ -86,8 +90,17 @@ typedef struct code_props {
void code_props_none_init (code_props *self);
/** Equivalent to \c code_props_none_init. */
#define CODE_PROPS_NONE_INIT \
{CODE_PROPS_NONE, NULL, EMPTY_LOCATION_INIT, false, false, NULL, NULL}
#define CODE_PROPS_NONE_INIT \
{ \
/* .kind = */ CODE_PROPS_NONE, \
/* .code = */ NULL, \
/* .location = */ EMPTY_LOCATION_INIT, \
/* .is_value_used = */ false, \
/* .is_predicate = */ false, \
/* .is_used = */ false, \
/* .rule = */ NULL, \
/* .named_ref = */ NULL \
}
/** Initialized by \c CODE_PROPS_NONE_INIT with no further modification. */
extern code_props const code_props_none;

View File

@@ -888,24 +888,20 @@ void
code_props_plain_init (code_props *self, char const *code,
location code_loc)
{
code_props_none_init (self);
self->kind = CODE_PROPS_PLAIN;
self->code = code;
self->location = code_loc;
self->is_value_used = false;
self->rule = NULL;
self->named_ref = NULL;
}
void
code_props_symbol_action_init (code_props *self, char const *code,
location code_loc)
{
code_props_none_init (self);
self->kind = CODE_PROPS_SYMBOL_ACTION;
self->code = code;
self->location = code_loc;
self->is_value_used = false;
self->rule = NULL;
self->named_ref = NULL;
}
void
@@ -913,10 +909,10 @@ code_props_rule_action_init (code_props *self, char const *code,
location code_loc, symbol_list *rule,
named_ref *name, bool is_predicate)
{
code_props_none_init (self);
self->kind = CODE_PROPS_RULE_ACTION;
self->code = code;
self->location = code_loc;
self->is_value_used = false;
self->rule = rule;
self->named_ref = name;
self->is_predicate = is_predicate;

View File

@@ -419,6 +419,15 @@ symbol_check_defined (symbol *sym)
sym->number = nvars++;
}
for (int i = 0; i < 2; ++i)
if (sym->props[i].kind == CODE_PROPS_NONE && sym->type_name)
{
semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
if (sem_type
&& sem_type->props[i].kind != CODE_PROPS_NONE)
sem_type->props[i].is_used = true;
}
/* Set the semantic type status associated to the current symbol to
'declared' so that we could check semantic types unnecessary uses. */
if (sym->type_name)
@@ -434,7 +443,16 @@ symbol_check_defined (symbol *sym)
static inline bool
semantic_type_check_defined (semantic_type *sem_type)
{
if (sem_type->status != declared)
if (sem_type->status == declared)
{
for (int i = 0; i < 2; ++i)
if (sem_type->props[i].kind != CODE_PROPS_NONE
&& ! sem_type->props[i].is_used)
warn_at (sem_type->location,
_("useless %s for type <%s>"),
code_props_type_string (i), sem_type->tag);
}
else
warn_at (sem_type->location,
_("type <%s> is used, but is not associated to any symbol"),
sem_type->tag);

View File

@@ -323,6 +323,51 @@ input.y:5.25-31: warning: type <type4> is used, but is not associated to any sym
AT_CLEANUP
## --------------------------------- ##
## Useless printers or destructors. ##
## --------------------------------- ##
AT_SETUP([Useless printers or destructors])
AT_DATA([[input.y]],
[[%token <type1> token1
%token <type2> token2
%token <type3> token3
%token <type4> token4
%token <type5> token51 token52
%token <type6> token61 token62
%token <type7> token7
%printer {} token1
%destructor {} token2
%printer {} token51
%destructor {} token61
%printer {} token7
%printer {} <type1>
%destructor {} <type2>
%printer {} <type3>
%destructor {} <type4>
%printer {} <type5>
%destructor {} <type6>
%destructor {} <type7>
%%
exp: "a";
]])
AT_BISON_CHECK([input.y], [0], [],
[[input.y:16.13-19: warning: useless %printer for type <type1>
input.y:17.16-22: warning: useless %destructor for type <type2>
]])
AT_CLEANUP
## ---------------------------------------- ##
## Unused values with default %destructor. ##
## ---------------------------------------- ##