warnings: useless semantic types

* src/symtab.h (symbol_list): Represent semantic types as structure
'semantic_type'.
* src/symlist.c (symbol_list_type_new): Allocate this structure.
(symbol_list_code_props_set): Set this semantic type's status to used if it
was not declared.
* src/symtab.c (semantic_types_sorted): New.
(semantic_type_new): Set the new semantic type's location appropriately.
(symbol_check_defined): If a symbol has a type, then set this type's status
to "declared".
(semantic_type_check_defined, semantic_type_check_defined_processor): Same
as symbol_check_defined and symbol_check_defined_processor, but for semantic
types.
(symbol_check_defined): Check semantic types usefulness.
* src/symtab.h (semantic_type): New fields 'location' and 'status'.
* src/symtab.h, src/symtab.c (semantic_type_new)
(semantic_type_from_uniqstr, semantic_type_get): Accept a location as a
supplementary argument.
* tests/input.at (Unassociated types used for printer of destructor): New.
* tests/c++.at (AT_CHECK_VARIANTS): Fix an error caught by this commit.
This commit is contained in:
Victor Santet
2012-06-18 15:44:38 +02:00
committed by Akim Demaille
parent 423ca9b50e
commit 9641b918ba
7 changed files with 105 additions and 12 deletions

17
NEWS
View File

@@ -2,6 +2,23 @@ GNU Bison NEWS
* Noteworthy changes in release ?.? (????-??-??) [?] * Noteworthy changes in release ?.? (????-??-??) [?]
** Warnings about useless semantic types
Bison now warns about useless (uninhabited) semantic types. Since
semantic types are not declared to Bison (they are defined in the opaque
%union structure), it is %printer/%destructor directives about useless
types that trigger the warning:
%token <type1> term
%type <type2> nterm
%printer {} <type1> <type3>
%destructor {} <type2> <type4>
%%
nterm: term { $$ = $1; };
3.28-34: warning: type <type3> is used, but is not associated to any symbol
4.28-34: warning: type <type4> is used, but is not associated to any symbol
** Warnings about undeclared symbols ** Warnings about undeclared symbols
Bison used to raise an error for %printer and %destructor directives for Bison used to raise an error for %printer and %destructor directives for

View File

@@ -66,7 +66,11 @@ symbol_list_type_new (uniqstr type_name, location loc)
symbol_list *res = xmalloc (sizeof *res); symbol_list *res = xmalloc (sizeof *res);
res->content_type = SYMLIST_TYPE; res->content_type = SYMLIST_TYPE;
res->content.type_name = type_name; res->content.sem_type = xmalloc (sizeof (semantic_type));
res->content.sem_type->tag = type_name;
res->content.sem_type->location = loc;
res->content.sem_type->status = undeclared;
res->location = res->sym_loc = loc; res->location = res->sym_loc = loc;
res->named_ref = NULL; res->named_ref = NULL;
res->next = NULL; res->next = NULL;
@@ -238,8 +242,11 @@ symbol_list_code_props_set (symbol_list *node, code_props_type kind,
break; break;
case SYMLIST_TYPE: case SYMLIST_TYPE:
semantic_type_code_props_set semantic_type_code_props_set
(semantic_type_get (node->content.type_name), (semantic_type_get (node->content.sem_type->tag,
&node->content.sem_type->location),
kind, &cprops); kind, &cprops);
if (node->content.sem_type->status == undeclared)
node->content.sem_type->status = used;
break; break;
case SYMLIST_DEFAULT_TAGGED: case SYMLIST_DEFAULT_TAGGED:
default_tagged_code_props_set (kind, &cprops); default_tagged_code_props_set (kind, &cprops);

View File

@@ -46,7 +46,7 @@ typedef struct symbol_list
/** /**
* The semantic type iff <tt>symbol_list::content_type = SYMLIST_TYPE</tt>. * The semantic type iff <tt>symbol_list::content_type = SYMLIST_TYPE</tt>.
*/ */
uniqstr type_name; semantic_type *sem_type;
} content; } content;
location location; location location;

View File

@@ -33,6 +33,7 @@
`-------------------------------------------------------------------*/ `-------------------------------------------------------------------*/
static symbol **symbols_sorted = NULL; static symbol **symbols_sorted = NULL;
static symbol **semantic_types_sorted = NULL;
/*------------------------. /*------------------------.
| Distinguished symbols. | | Distinguished symbols. |
@@ -118,12 +119,14 @@ code_props_type_string (code_props_type kind)
`----------------------------------------*/ `----------------------------------------*/
static semantic_type * static semantic_type *
semantic_type_new (uniqstr tag) semantic_type_new (uniqstr tag, const location *loc)
{ {
semantic_type *res = xmalloc (sizeof *res); semantic_type *res = xmalloc (sizeof *res);
uniqstr_assert (tag); uniqstr_assert (tag);
res->tag = tag; res->tag = tag;
if (loc)
res->location = *loc;
for (int i = 0; i < CODE_PROPS_SIZE; ++i) for (int i = 0; i < CODE_PROPS_SIZE; ++i)
code_props_none_init (&res->props[i]); code_props_none_init (&res->props[i]);
@@ -283,7 +286,7 @@ symbol_code_props_get (symbol const *sym,
if (sym->type_name) if (sym->type_name)
{ {
code_props const *code = code_props const *code =
&semantic_type_get (sym->type_name)->props[kind]; &semantic_type_get (sym->type_name, NULL)->props[kind];
if (code->code) if (code->code)
return code; return code;
} }
@@ -416,6 +419,26 @@ symbol_check_defined (symbol *sym)
sym->number = nvars++; sym->number = nvars++;
} }
/* 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)
{
semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
if (sem_type)
sem_type->status = declared;
}
return true;
}
static inline bool
semantic_type_check_defined (semantic_type *sem_type)
{
if (sem_type->status != declared)
warn_at (sem_type->location,
_("type <%s> is used, but is not associated to any symbol"),
sem_type->tag);
return true; return true;
} }
@@ -425,6 +448,13 @@ symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED)
return symbol_check_defined (sym); return symbol_check_defined (sym);
} }
static bool
semantic_type_check_defined_processor (void *sem_type,
void *null ATTRIBUTE_UNUSED)
{
return semantic_type_check_defined (sem_type);
}
void void
symbol_make_alias (symbol *sym, symbol *str, location loc) symbol_make_alias (symbol *sym, symbol *str, location loc)
@@ -690,7 +720,7 @@ symbol_from_uniqstr (const uniqstr key, location loc)
`-----------------------------------------------------------------------*/ `-----------------------------------------------------------------------*/
semantic_type * semantic_type *
semantic_type_from_uniqstr (const uniqstr key) semantic_type_from_uniqstr (const uniqstr key, const location *loc)
{ {
semantic_type probe; semantic_type probe;
semantic_type *entry; semantic_type *entry;
@@ -701,7 +731,7 @@ semantic_type_from_uniqstr (const uniqstr key)
if (!entry) if (!entry)
{ {
/* First insertion in the hash. */ /* First insertion in the hash. */
entry = semantic_type_new (key); entry = semantic_type_new (key, loc);
if (!hash_insert (semantic_type_table, entry)) if (!hash_insert (semantic_type_table, entry))
xalloc_die (); xalloc_die ();
} }
@@ -727,9 +757,9 @@ symbol_get (const char *key, location loc)
`-----------------------------------------------------------------------*/ `-----------------------------------------------------------------------*/
semantic_type * semantic_type *
semantic_type_get (const char *key) semantic_type_get (const char *key, const location *loc)
{ {
return semantic_type_from_uniqstr (uniqstr_new (key)); return semantic_type_from_uniqstr (uniqstr_new (key), loc);
} }
@@ -819,6 +849,8 @@ symbols_check_defined (void)
{ {
symbols_do (symbol_check_defined_processor, NULL, symbols_do (symbol_check_defined_processor, NULL,
symbol_table, symbols_sorted); symbol_table, symbols_sorted);
symbols_do (semantic_type_check_defined_processor, NULL,
semantic_type_table, semantic_types_sorted);
} }
/*------------------------------------------------------------------. /*------------------------------------------------------------------.

View File

@@ -232,6 +232,13 @@ typedef struct {
/** The key, name of the semantic type. */ /** The key, name of the semantic type. */
uniqstr tag; uniqstr tag;
/** The location of its first occurence. */
location location;
/** Its status : "undeclared", "used" or "declared".
It cannot be "needed". */
status status;
/** Any \c %destructor and %printer declared for this /** Any \c %destructor and %printer declared for this
semantic type. */ semantic type. */
code_props props[CODE_PROPS_SIZE]; code_props props[CODE_PROPS_SIZE];
@@ -239,10 +246,11 @@ typedef struct {
} semantic_type; } semantic_type;
/** Fetch (or create) the semantic type associated to KEY. */ /** Fetch (or create) the semantic type associated to KEY. */
semantic_type *semantic_type_from_uniqstr (const uniqstr key); semantic_type *semantic_type_from_uniqstr (const uniqstr key,
const location *loc);
/** Fetch (or create) the semantic type associated to KEY. */ /** Fetch (or create) the semantic type associated to KEY. */
semantic_type *semantic_type_get (const char *key); semantic_type *semantic_type_get (const char *key, const location *loc);
/** Set the \c destructor or \c printer associated with \c type. */ /** Set the \c destructor or \c printer associated with \c type. */
void semantic_type_code_props_set (semantic_type *type, void semantic_type_code_props_set (semantic_type *type,

View File

@@ -99,7 +99,7 @@ typedef std::list<std::string> strings_type;
%type <::std::list<std::string>> list result; %type <::std::list<std::string>> list result;
%printer { debug_stream() << $][$; } %printer { debug_stream() << $][$; }
<int> <::std::string> <::std::list<::std::string>>; <int> <::std::string> <::std::list<std::string>>;
%% %%
result: result:

View File

@@ -294,6 +294,35 @@ input.y:1.13-15: warning: symbol foo is used, but is not defined as a token and
AT_CLEANUP AT_CLEANUP
## ----------------------------------------------------- ##
## Unassociated types used for a printer or destructor. ##
## ----------------------------------------------------- ##
AT_SETUP([Unassociated types used for a printer or destructor])
AT_DATA([[input.y]],
[[%token <type1> tag1
%type <type2> tag2
%printer { } <type1> <type3>
%destructor { } <type2> <type4>
%%
exp: tag1 { $1; }
| tag2 { $1; }
tag2: "a" { $$; }
]])
AT_BISON_CHECK([input.y], [0], [],
[[input.y:4.22-28: warning: type <type3> is used, but is not associated to any symbol
input.y:5.25-31: warning: type <type4> is used, but is not associated to any symbol
]])
AT_CLEANUP
## ---------------------------------------- ## ## ---------------------------------------- ##
## Unused values with default %destructor. ## ## Unused values with default %destructor. ##
## ---------------------------------------- ## ## ---------------------------------------- ##