]> git.saurik.com Git - bison.git/commitdiff
warnings: raise warning for useless printers or destructors
authorVictor Santet <victor.santet@epita.fr>
Thu, 14 Jun 2012 12:20:07 +0000 (14:20 +0200)
committerAkim Demaille <akim@lrde.epita.fr>
Tue, 26 Jun 2012 13:57:46 +0000 (15:57 +0200)
* 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>
NEWS
src/scan-code.h
src/scan-code.l
src/symtab.c
tests/input.at

diff --git a/NEWS b/NEWS
index 96a5deb10a1d404ce646f9055962957964da8e10..286547696d24325ccfac0396d20e976f642ac563 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
index 3fa5ea9a00d4796386a3df661afc895078018c7f..ec5579f3aeaba6b7d4637ebbab2870513a63a31f 100644 (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;
index b8c0c1b069191c656686d68c5a3cea917a4958cb..eed0c9b7ed05b330b31b372d11c9e8e1ecb62efd 100644 (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;
index da89afeb9291077d3e6334d3dc9fa801c3b9bcfa..c65bd201e5c08f2f77ba70c5dbdc00c555f8b952 100644 (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);
index bb37be0a5ee21bcab258572eee9ce30ffe0dc6e7..053e3583942e8a41ee1a292cbe5941c86402df51 100644 (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.  ##
 ## ---------------------------------------- ##