]> git.saurik.com Git - bison.git/commitdiff
warnings: useless semantic types
authorVictor Santet <victor.santet@epita.fr>
Mon, 18 Jun 2012 13:44:38 +0000 (15:44 +0200)
committerAkim Demaille <akim@lrde.epita.fr>
Mon, 25 Jun 2012 09:29:14 +0000 (11:29 +0200)
* 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
src/symlist.c
src/symlist.h
src/symtab.c
src/symtab.h
tests/c++.at
tests/input.at

diff --git a/NEWS b/NEWS
index 0dfc63f034f25853f294b87b8f8d126f2a736a13..96a5deb10a1d404ce646f9055962957964da8e10 100644 (file)
--- 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 <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
 
   Bison used to raise an error for %printer and %destructor directives for
index abea6ce75e24e3db119d783627edb3b0464c86b1..48828315304f0bc99bf4ae5828938f2de24b4277 100644 (file)
@@ -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);
index 0bd4f3b09f5b62cfe164e7e6e1b0491e34a1bfa3..3b03713b3fd368c779fce5386f5699f6dd92d899 100644 (file)
@@ -46,7 +46,7 @@ typedef struct symbol_list
     /**
      * The semantic type iff <tt>symbol_list::content_type = SYMLIST_TYPE</tt>.
      */
-    uniqstr type_name;
+    semantic_type *sem_type;
   } content;
   location location;
 
index 14d107c9ef1dc142275c01a22c2845e512ff7685..da89afeb9291077d3e6334d3dc9fa801c3b9bcfa 100644 (file)
@@ -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);
 }
 
 /*------------------------------------------------------------------.
index 70b4a8174a48eae92b93826f01b548ee6ed514fc..84113394b5fcce7612b311036c2cfced7194a262 100644 (file)
@@ -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,
index 2d5a026dce717cd966f928be639d82ac9c67bf95..9f70f15f670a2632f79593dcfb5aee6d7b485c61 100644 (file)
@@ -99,7 +99,7 @@ typedef std::list<std::string> strings_type;
 %type <::std::list<std::string>> list result;
 
 %printer { debug_stream() << $][$; }
-  <int> <::std::string> <::std::list<::std::string>>;
+  <int> <::std::string> <::std::list<std::string>>;
 %%
 
 result:
index 200fa076fa00fed03ac6daaa101c6075b5046333..bb37be0a5ee21bcab258572eee9ce30ffe0dc6e7 100644 (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
 
 
+## ----------------------------------------------------- ##
+## 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.  ##
 ## ---------------------------------------- ##