From 9641b918bae9eb8d0bb9099ab6d9d46383ba8bc9 Mon Sep 17 00:00:00 2001 From: Victor Santet Date: Mon, 18 Jun 2012 15:44:38 +0200 Subject: [PATCH] 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. --- NEWS | 17 +++++++++++++++++ src/symlist.c | 11 +++++++++-- src/symlist.h | 2 +- src/symtab.c | 44 ++++++++++++++++++++++++++++++++++++++------ src/symtab.h | 12 ++++++++++-- tests/c++.at | 2 +- tests/input.at | 29 +++++++++++++++++++++++++++++ 7 files changed, 105 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 0dfc63f0..96a5deb1 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,23 @@ GNU Bison NEWS * 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 term + %type nterm + %printer {} + %destructor {} + %% + nterm: term { $$ = $1; }; + + 3.28-34: warning: type is used, but is not associated to any symbol + 4.28-34: warning: type is used, but is not associated to any symbol + ** Warnings about undeclared symbols Bison used to raise an error for %printer and %destructor directives for diff --git a/src/symlist.c b/src/symlist.c index abea6ce7..48828315 100644 --- a/src/symlist.c +++ b/src/symlist.c @@ -66,7 +66,11 @@ symbol_list_type_new (uniqstr type_name, location loc) symbol_list *res = xmalloc (sizeof *res); 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->named_ref = NULL; res->next = NULL; @@ -238,8 +242,11 @@ symbol_list_code_props_set (symbol_list *node, code_props_type kind, break; case SYMLIST_TYPE: 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); + if (node->content.sem_type->status == undeclared) + node->content.sem_type->status = used; break; case SYMLIST_DEFAULT_TAGGED: default_tagged_code_props_set (kind, &cprops); diff --git a/src/symlist.h b/src/symlist.h index 0bd4f3b0..3b03713b 100644 --- a/src/symlist.h +++ b/src/symlist.h @@ -46,7 +46,7 @@ typedef struct symbol_list /** * The semantic type iff symbol_list::content_type = SYMLIST_TYPE. */ - uniqstr type_name; + semantic_type *sem_type; } content; location location; diff --git a/src/symtab.c b/src/symtab.c index 14d107c9..da89afeb 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -33,6 +33,7 @@ `-------------------------------------------------------------------*/ static symbol **symbols_sorted = NULL; +static symbol **semantic_types_sorted = NULL; /*------------------------. | Distinguished symbols. | @@ -118,12 +119,14 @@ code_props_type_string (code_props_type kind) `----------------------------------------*/ static semantic_type * -semantic_type_new (uniqstr tag) +semantic_type_new (uniqstr tag, const location *loc) { semantic_type *res = xmalloc (sizeof *res); uniqstr_assert (tag); res->tag = tag; + if (loc) + res->location = *loc; for (int i = 0; i < CODE_PROPS_SIZE; ++i) code_props_none_init (&res->props[i]); @@ -283,7 +286,7 @@ symbol_code_props_get (symbol const *sym, if (sym->type_name) { code_props const *code = - &semantic_type_get (sym->type_name)->props[kind]; + &semantic_type_get (sym->type_name, NULL)->props[kind]; if (code->code) return code; } @@ -416,6 +419,26 @@ symbol_check_defined (symbol *sym) 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; } @@ -425,6 +448,13 @@ symbol_check_defined_processor (void *sym, void *null ATTRIBUTE_UNUSED) 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 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_from_uniqstr (const uniqstr key) +semantic_type_from_uniqstr (const uniqstr key, const location *loc) { semantic_type probe; semantic_type *entry; @@ -701,7 +731,7 @@ semantic_type_from_uniqstr (const uniqstr key) if (!entry) { /* First insertion in the hash. */ - entry = semantic_type_new (key); + entry = semantic_type_new (key, loc); if (!hash_insert (semantic_type_table, entry)) xalloc_die (); } @@ -727,9 +757,9 @@ symbol_get (const char *key, location loc) `-----------------------------------------------------------------------*/ 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, symbol_table, symbols_sorted); + symbols_do (semantic_type_check_defined_processor, NULL, + semantic_type_table, semantic_types_sorted); } /*------------------------------------------------------------------. diff --git a/src/symtab.h b/src/symtab.h index 70b4a817..84113394 100644 --- a/src/symtab.h +++ b/src/symtab.h @@ -232,6 +232,13 @@ typedef struct { /** The key, name of the semantic type. */ 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 semantic type. */ code_props props[CODE_PROPS_SIZE]; @@ -239,10 +246,11 @@ typedef struct { } semantic_type; /** 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. */ -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. */ void semantic_type_code_props_set (semantic_type *type, diff --git a/tests/c++.at b/tests/c++.at index 2d5a026d..9f70f15f 100644 --- a/tests/c++.at +++ b/tests/c++.at @@ -99,7 +99,7 @@ typedef std::list strings_type; %type <::std::list> list result; %printer { debug_stream() << $][$; } - <::std::string> <::std::list<::std::string>>; + <::std::string> <::std::list>; %% result: diff --git a/tests/input.at b/tests/input.at index 200fa076..bb37be0a 100644 --- a/tests/input.at +++ b/tests/input.at @@ -294,6 +294,35 @@ input.y:1.13-15: warning: symbol foo is used, but is not defined as a token and 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 tag1 +%type tag2 + +%printer { } +%destructor { } + +%% + +exp: tag1 { $1; } + | tag2 { $1; } + +tag2: "a" { $$; } +]]) + +AT_BISON_CHECK([input.y], [0], [], +[[input.y:4.22-28: warning: type is used, but is not associated to any symbol +input.y:5.25-31: warning: type is used, but is not associated to any symbol +]]) + +AT_CLEANUP + + ## ---------------------------------------- ## ## Unused values with default %destructor. ## ## ---------------------------------------- ## -- 2.47.2