]> git.saurik.com Git - bison.git/commitdiff
Merge remote-tracking branch 'origin/maint'
authorTheophile Ranquet <ranquet@lrde.epita.fr>
Thu, 6 Dec 2012 10:43:02 +0000 (11:43 +0100)
committerTheophile Ranquet <ranquet@lrde.epita.fr>
Thu, 6 Dec 2012 12:38:43 +0000 (13:38 +0100)
* origin/maint:
  misc: pacify the Tiny C Compiler
  cpp: make the check of Flex version portable
  misc: require getline
  c++: support wide strings for file names
  doc: document carets
  tests: enhance existing tests with carets
  errors: show carets
  getargs: add support for --flags/-f

Conflicts:
doc/bison.texi
m4/.gitignore
src/complain.c
src/flex-scanner.h
src/getargs.c
src/getargs.h
src/gram.c
src/main.c
tests/headers.at

21 files changed:
1  2 
NEWS
THANKS
bootstrap.conf
data/location.cc
doc/bison.texi
lib/.gitignore
m4/.gitignore
src/complain.c
src/flex-scanner.h
src/getargs.c
src/getargs.h
src/gram.c
src/location.c
src/location.h
src/main.c
tests/actions.at
tests/conflicts.at
tests/input.at
tests/named-refs.at
tests/reduce.at
tests/regression.at

diff --cc NEWS
Simple merge
diff --cc THANKS
Simple merge
diff --cc bootstrap.conf
index cddc571b6dedd3462c28b20387c4ca22611a298e,9dccd00144e3cf9b0af245f0c36c65f9416d3f42..feff5ff0817f34e80c425aff4e09763f9615b10e
@@@ -20,12 -20,13 +20,14 @@@ gnulib_modules=
    argmatch assert calloc-posix close closeout config-h c-strcase
    configmake
    dirname
-   error extensions fdl fopen-safer getopt-gnu
+   error extensions fdl fopen-safer
+   getline
+   getopt-gnu
    gettext git-version-gen gitlog-to-changelog
    gpl-3.0 hash inttypes isnan javacomp-script
 -  javaexec-script ldexpl malloc-gnu mbschr mbsrchr
 +  javaexec-script ldexpl malloc-gnu
    mbswidth
 +  non-recursive-gnulib-prefix-hack
    obstack
    obstack-printf
    perror progname
Simple merge
diff --cc doc/bison.texi
index 874e68e17a4ba78827d54c668c6727fd69fff55a,06af0884350e6b775cdb87fc19fd8502d25dc3af..28af1ae65e390c4e793ba46fb223a4e01bfef242
@@@ -9586,26 -9240,55 +9586,76 @@@ A category can be turned off by prefixi
  instance, @option{-Wno-yacc} will hide the warnings about
  POSIX Yacc incompatibilities.
  
 +@item -Werror[=@var{category}]
 +@itemx -Wno-error[=@var{category}]
 +Enable warnings falling in @var{category}, and treat them as errors.  If no
 +@var{category} is given, it defaults to making all enabled warnings into errors.
 +
 +@var{category} is the same as for @option{--warnings}, with the exception that
 +it may not be prefixed with @samp{no-} (see above).
 +
 +Prefixed with @samp{no}, it deactivates the error treatment for this
 +@var{category}. However, the warning itself won't be disabled, or enabled, by
 +this option.
 +
 +Note that the precedence of the @samp{=} and @samp{,} operators is such that
 +the following commands are @emph{not} equivalent, as the first will not treat
 +S/R conflicts as errors.
 +
 +@example
 +$ bison -Werror=yacc,conflicts-sr input.y
 +$ bison -Werror=yacc,error=conflicts-sr input.y
 +@end example
++
+ @item -f [@var{feature}]
+ @itemx --feature[=@var{feature}]
+ Activate miscellaneous @var{feature}. @var{feature} can be one of:
+ @table @code
+ @item caret
+ @itemx diagnostics-show-caret
+ Show caret errors, in a manner similar to GCC's
+ @option{-fdiagnostics-show-caret}, or Clang's @option{-fcaret-diagnotics}. The
+ location provided with the message is used to quote the corresponding line of
+ the source file, underlining the important part of it with carets (^). Here is
+ an example, using the following file @file{input.y}:
+ @example
+ %type <ival> exp
+ %%
+ exp: exp '+' exp @{ $exp = $1 + $2; @};
+ @end example
+ When invoked with @option{-fcaret}, Bison will report:
+ @example
+ @group
+ input.y:3.20-23: error: ambiguous reference: '$exp'
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+                     ^^^^
+ @end group
+ @group
+ input.y:3.1-3:       refers to: $exp at $$
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+  ^^^
+ @end group
+ @group
+ input.y:3.6-8:       refers to: $exp at $1
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+       ^^^
+ @end group
+ @group
+ input.y:3.14-16:     refers to: $exp at $3
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+               ^^^
+ @end group
+ @group
+ input.y:3.32-33: error: $2 of 'exp' has no declared type
+  exp: exp '+' exp @{ $exp = $1 + $2; @};
+                                 ^^
+ @end group
+ @end example
+ @end table
  @end table
  
  @noindent
diff --cc lib/.gitignore
index ba37d129a39e3ddcdcb50559cb030dadf013fa77,2e92c2ffd8eb4ddaa510e6c99d1e447bc84f05f4..74cb3083bf5b6b4f0406b2df1b84d3753a7a7f12
  /isnanf.c
  /isnanl-nolibm.h
  /isnanl.c
--/iswblank.c
  /itold.c
  /ldexpl.c
  /localcharset.c
  /malloc.c
  /math.h
  /math.in.h
--/mbchar.c
--/mbchar.h
  /mbrtowc.c
 -/mbschr.c
  /mbsinit.c
 -/mbsrchr.c
  /mbswidth.c
  /mbswidth.h
--/mbuiter.h
  /memchr.c
  /memchr.valgrind
  /msvc-inval.c
  /stripslash.c
  /strndup.c
  /strnlen.c
--/strnlen1.c
--/strnlen1.h
  /strtol.c
  /strtoul.c
  /strverscmp.c
  /xsize.h
  /xstrndup.c
  /xstrndup.h
 -/xmemdup0.c
 -/xmemdup0.h
 -/sys_types.in.h
 -/obstack_printf.c
  /binary-io.c
 -/mbuiter.c
  /xsize.c
--/bitrotate.c
--/math.c
--/sig-handler.c
--/stdio.c
--/unistd.c
--/wctype-h.c
+ /getdelim.c
+ /getline.c
diff --cc m4/.gitignore
index 80193dbb1778cd0db3a88e4f1188ea0eb0aa5201,8b665097b182d45cfcb0889fff21c0e66e6badb7..242ac2a7a7d60827b0f1b6fafb129afc59a2c816
@@@ -63,7 -62,7 +63,6 @@@
  /isnand.m4
  /isnanf.m4
  /isnanl.m4
--/iswblank.m4
  /javacomp.m4
  /javaexec.m4
  /largefile.m4
@@@ -82,8 -81,8 +81,6 @@@
  /longlong.m4
  /malloc.m4
  /math_h.m4
--/mbchar.m4
--/mbiter.m4
  /mbrtowc.m4
  /mbsinit.m4
  /mbstate_t.m4
  /xstrndup.m4
  /obstack-printf.m4
  /extern-inline.m4
 +/non-recursive-gnulib-prefix-hack.m4
+ /getdelim.m4
+ /getline.m4
++/inline.m4
diff --cc src/complain.c
index 2e4e71afb92e1deac07c1d9e7bd69643fd746c2a,ede0ccf4f5cb122d601e329dc5eeaafb1a5997d7..ee1b4a19ae13e103924c5797efe65bba72359474
@@@ -107,45 -72,84 +107,48 @@@ error_message (const location *loc, war
      fprintf (stderr, "%s: ", prefix);
  
    vfprintf (stderr, message, args);
 +  warnings_print_categories (flags);
    {
      size_t l = strlen (message);
-     if (l < 2 || message[l-2] != ':' || message[l-1] != ' ')
+     if (l < 2 || message[l - 2] != ':' || message[l - 1] != ' ')
        {
          putc ('\n', stderr);
          fflush (stderr);
+         if (loc && feature_flag & feature_caret)
+           location_caret (stderr, *loc);
        }
    }
+   fflush (stderr);
  }
  
 -/** Wrap error_message() with varargs handling. */
 -#define ERROR_MESSAGE(Loc, Prefix, Message)   \
 -{                                             \
 -  va_list args;                                       \
 -  va_start (args, Message);                   \
 -  error_message (Loc, Prefix, Message, args); \
 -  va_end (args);                              \
 -}
 -
 -
 -/*--------------------------------.
 -| Report a warning, and proceed.  |
 -`--------------------------------*/
 -
 -void
 -set_warning_issued (void)
 -{
 -  static bool warning_issued = false;
 -  if (!warning_issued && (warnings_flag & warnings_error))
 -    {
 -      fprintf (stderr, "%s: warnings being treated as errors\n", program_name);
 -      complaint_issued = true;
 -    }
 -  warning_issued = true;
 -}
 -
 -void
 -warn_at (location loc, const char *message, ...)
 -{
 -  if (!(warnings_flag & warnings_other))
 -    return;
 -  set_warning_issued ();
 -  ERROR_MESSAGE (&loc, _("warning"), message);
 -}
 -
 -void
 -warn_at_indent (location loc, unsigned *indent,
 -                const char *message, ...)
 -{
 -  if (!(warnings_flag & warnings_other))
 -    return;
 -  set_warning_issued ();
 -  indent_ptr = indent;
 -  ERROR_MESSAGE (&loc, *indent ? NULL : _("warning"), message);
 -}
 -
 -void
 -warn (const char *message, ...)
 +/** Raise a complaint. That can be a fatal error, a complaint or just a
 +    warning.  */
 +static inline void
 +complains (const location *loc, warnings flags, const char *message,
 +           va_list args)
  {
 -  if (!(warnings_flag & warnings_other))
 -    return;
 -  set_warning_issued ();
 -  ERROR_MESSAGE (NULL, _("warning"), message);
 +  const char* prefix =
 +    flags & fatal ? _("fatal error")
 +    : flags & (errors_flag | complaint) ? _("error")
 +    : _("warning");
 +
 +  if ((flags & complaint) && complaint_status < status_complaint)
 +    complaint_status = status_complaint;
 +  else if ((flags & (warnings_flag & errors_flag)) && ! complaint_status)
 +    complaint_status = status_warning_as_error;
 +  if (flags & (warnings_flag | fatal | complaint))
 +    error_message (loc, flags, prefix, message, args);
 +  if (flags & fatal)
 +    exit (EXIT_FAILURE);
  }
  
 -
 -/*-----------------------------------------------------------.
 -| An error has occurred, but we can proceed, and die later.  |
 -`-----------------------------------------------------------*/
 -
  void
 -complain_at (location loc, const char *message, ...)
 +complain (location const *loc, warnings flags, const char *message, ...)
  {
 -  ERROR_MESSAGE (&loc, _("error"), message);
 -  complaint_issued = true;
 +  va_list args;
 +  va_start (args, message);
 +  complains (loc, flags, message, args);
 +  va_end (args);
  }
  
  void
Simple merge
diff --cc src/getargs.c
index 77c1cbfbebd70b7c7d1afb4e2686eb94c2e0cb06,ab2a28e828739c44dd90381367f8dc7414556fd8..0d43186f23c2713573e79368b12044216df0b117
@@@ -46,8 -63,11 +46,9 @@@ bool yacc_flag; /* for -y *
  bool nondeterministic_parser = false;
  bool glr_parser = false;
  
+ int feature_flag = feature_none;
  int report_flag = report_none;
  int trace_flag = trace_none;
 -int warnings_flag = warnings_conflicts_sr | warnings_conflicts_rr
 -                    | warnings_other;
  
  static struct bison_language const valid_languages[] = {
    { "c", "c-skel.m4", ".c", ".h", true },
@@@ -605,37 -621,41 +638,41 @@@ getargs (int argc, char *argv[]
                                          c == 'D' ? MUSCLE_PERCENT_DEFINE_D
                                                   : MUSCLE_PERCENT_DEFINE_F);
          }
 -      break;
 +        break;
  
        case 'I':
 -      include = AS_FILE_NAME (optarg);
 -      break;
 +        include = AS_FILE_NAME (optarg);
 +        break;
  
        case 'L':
 -      language_argmatch (optarg, command_line_prio,
 -                         command_line_location ());
 -      break;
 +        language_argmatch (optarg, command_line_prio,
 +                           command_line_location ());
 +        break;
  
        case 'S':
 -      skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
 -                    command_line_location ());
 -      break;
 +        skeleton_arg (AS_FILE_NAME (optarg), command_line_prio,
 +                      command_line_location ());
 +        break;
  
        case 'T':
 -      FLAGS_ARGMATCH (trace, optarg);
 -      break;
 +        FLAGS_ARGMATCH (trace, optarg, trace_all);
 +        break;
  
        case 'V':
 -      version ();
 -      exit (EXIT_SUCCESS);
 +        version ();
 +        exit (EXIT_SUCCESS);
  
 -        FLAGS_ARGMATCH (feature, optarg);
+       case 'f':
++        FLAGS_ARGMATCH (feature, optarg, feature_all);
+         break;
        case 'W':
 -      FLAGS_ARGMATCH (warnings, optarg);
 -      break;
 +        FLAGS_ARGMATCH (warnings, optarg, Wall);
 +        break;
  
        case 'b':
 -      spec_file_prefix = AS_FILE_NAME (optarg);
 -      break;
 +        spec_file_prefix = AS_FILE_NAME (optarg);
 +        break;
  
        case 'd':
          /* Here, the -d and --defines options are differentiated.  */
diff --cc src/getargs.h
index 4eb3981220476ba8e219421f628e024a0aab0f38,b2126fc21319bc85a02471b85637f400f368518b..3c081fe321b826d77fa029b38af8f01cdb8ed43a
@@@ -108,6 -112,36 +108,18 @@@ enum trac
  /** What debug items bison displays during its run.  */
  extern int trace_flag;
  
 -/*-------------.
 -| --warnings.  |
 -`-------------*/
 -
 -enum warnings
 -  {
 -    warnings_none             = 0,      /**< Issue no warnings.  */
 -    warnings_error            = 1 << 0, /**< Warnings are treated as errors.  */
 -    warnings_midrule_values   = 1 << 1, /**< Unset or unused midrule values.  */
 -    warnings_yacc             = 1 << 2, /**< POSIXME.  */
 -    warnings_conflicts_sr     = 1 << 3, /**< S/R conflicts.  */
 -    warnings_conflicts_rr     = 1 << 4, /**< R/R conflicts.  */
 -    warnings_other            = 1 << 5, /**< All other warnings.  */
 -    warnings_all              = ~warnings_error /**< All above warnings.  */
 -  };
 -/** What warnings are issued.  */
 -extern int warnings_flag;
 -
+ /*-------------.
+ | --features.  |
+ `-------------*/
+ enum feature
+   {
+     feature_none  = 0,         /**< No additional feature.  */
+     feature_caret = 1 << 0,    /**< Enhance the output of errors with carets.  */
+     feature_all   = ~0         /**< All above features.  */
+   };
+ /** What additional features to use.  */
+ extern int feature_flag;
  
  /** Process the command line arguments.
   *
diff --cc src/gram.c
index f58ac3b5aea2fc1964e4cb566f8284e9140127f6,5730e596026729c24c2cec1f7bd4f85527d92a8b..dbcf8a213188c548bc2d65ed72dffb24d8b461ec
@@@ -305,19 -304,22 +305,24 @@@ grammar_dump (FILE *out, const char *ti
  void
  grammar_rules_useless_report (const char *message)
  {
 -  rule_number r;
 -  for (r = 0; r < nrules ; ++r)
 -    if (!rules[r].useful)
 -      {
 -        if (feature_flag & feature_caret)
 -          warn_at (rules[r].location, "%s", message);
 -        else
 +  warnings w = Wother;
 +  if (warnings_flag & w)
 +    {
 +      rule_number r;
 +      for (r = 0; r < nrules ; ++r)
 +        if (!rules[r].useful)
            {
-             complain (&rules[r].location, w | silent, "%s: ", message);
-             rule_print (&rules[r], stderr);
-             warnings_print_categories (w);
-             fprintf (stderr, "\n");
 -            warn_at (rules[r].location, "%s: ", message);
 -            if (warnings_flag & warnings_other)
++            if (feature_flag & feature_caret)
++              complain (&rules[r].location, w, "%s", message);
++            else
+               {
++                complain (&rules[r].location, w | silent, "%s: ", message);
+                 rule_print (&rules[r], stderr);
 -                fflush (stderr);
++                warnings_print_categories (w);
++                fprintf (stderr, "\n");
+               }
            }
 -      }
 +    }
  }
  
  void
diff --cc src/location.c
Simple merge
diff --cc src/location.h
Simple merge
diff --cc src/main.c
index 39b39c7a5902f6bc33e844c65c3ffe9e9823a762,184d789dd7a7cf2a640017f569dd8c48392062c2..5386aa717f21d7d7ddc55c7e66f3131b712e4edc
@@@ -215,5 -216,7 +215,7 @@@ main (int argc, char *argv[]
    timevar_stop (TV_TOTAL);
    timevar_print (stderr);
  
 -  return complaint_issued ? EXIT_FAILURE : EXIT_SUCCESS;
+   cleanup_caret ();
 +  return complaint_status ? EXIT_FAILURE : EXIT_SUCCESS;
  }
index 6d160efdc9667f1a1487b8cf98253c39ec6654c9,ba46fe36c346d67bfe80fc124ac7f0389a0a538e..cd7a58b6799740c44ad17f5074436c0a8e185727
@@@ -1323,12 -1300,19 +1323,27 @@@ main (void
  AT_BISON_OPTION_POPDEFS
  
  AT_BISON_CHECK([-o input.c input.y], 0,,
 -[[input.y:33.3-23: warning: unset value: $$
 -input.y:30.3-35.37: warning: unused value: $3
 +[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
 +input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
 +input.y:33.3-23: warning: unset value: $$ [-Wother]
 +input.y:30.3-35.37: warning: unused value: $3 [-Wother]
  ]])
  
 -[[input.y:33.3-23: warning: unset value: $$
+ AT_BISON_CHECK([-fcaret -o input.c input.y], 0,,
 -input.y:30.3-35.37: warning: unused value: $3
++[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
++ %printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
++                                                                      ^^^
++input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
++ %printer { fprintf (yyoutput, "<*> printer should not be called"); } <*>
++                                                                      ^^^
++input.y:33.3-23: warning: unset value: $$ [-Wother]
+    {           @$ = 4; } // Only used.
+    ^^^^^^^^^^^^^^^^^^^^^
++input.y:30.3-35.37: warning: unused value: $3 [-Wother]
+    {           @$ = 1; } // Not set or used.
+    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ]])
  AT_COMPILE([input])
  AT_PARSER_CHECK([./input], 1,,
  [[Starting parse
index 8b04449c732998197477f2fc2ebace711c6a66ba,5653b481f4f93248a176c332074385dcc4c45862..c7ed2fe42a8990ddbe67494a50f09aa637b34997
@@@ -37,9 -38,15 +37,15 @@@ e: 'e' | /* Nothing. */
  ]])
  
  AT_BISON_CHECK([-o input.c input.y], 0, [],
 -[[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */
 +[[input.y:4.9: warning: rule useless in parser due to conflicts: e: /* empty */ [-Wother]
  ]])
  
 -[[input.y:4.9: warning: rule useless in parser due to conflicts
+ AT_BISON_CHECK([-fcaret -o input.c input.y], 0, [],
++[[input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
+  e: 'e' | /* Nothing. */;
+          ^
+ ]])
  AT_CLEANUP
  
  
diff --cc tests/input.at
Simple merge
Simple merge
diff --cc tests/reduce.at
index 2d9093f0f63efea5c4fa0d2b5ddb1dcda76fcaf9,47f923cfdd319bb216e9dd5fc755a57c047b7ee0..8ac894c0655f5cb67ccba9cfb98ebcf099d45dfe
@@@ -142,27 -142,86 +142,86 @@@ useless8: '8'
  useless9: '9';
  ]])
  
 -[[input.y: warning: 9 nonterminals useless in grammar
 -input.y: warning: 9 rules useless in grammar
 -input.y:6.1-8: warning: nonterminal useless in grammar: useless1
+ AT_BISON_CHECK([[-fcaret input.y]], 0, [],
 -input.y:7.1-8: warning: nonterminal useless in grammar: useless2
++[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
++input.y: warning: 9 rules useless in grammar [-Wother]
++input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
+  useless1: '1';
+  ^^^^^^^^
 -input.y:8.1-8: warning: nonterminal useless in grammar: useless3
++input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
+  useless2: '2';
+  ^^^^^^^^
 -input.y:9.1-8: warning: nonterminal useless in grammar: useless4
++input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
+  useless3: '3';
+  ^^^^^^^^
 -input.y:10.1-8: warning: nonterminal useless in grammar: useless5
++input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
+  useless4: '4';
+  ^^^^^^^^
 -input.y:11.1-8: warning: nonterminal useless in grammar: useless6
++input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
+  useless5: '5';
+  ^^^^^^^^
 -input.y:12.1-8: warning: nonterminal useless in grammar: useless7
++input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
+  useless6: '6';
+  ^^^^^^^^
 -input.y:13.1-8: warning: nonterminal useless in grammar: useless8
++input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
+  useless7: '7';
+  ^^^^^^^^
 -input.y:14.1-8: warning: nonterminal useless in grammar: useless9
++input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
+  useless8: '8';
+  ^^^^^^^^
 -input.y:6.11-13: warning: rule useless in grammar
++input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
+  useless9: '9';
+  ^^^^^^^^
 -input.y:7.11-13: warning: rule useless in grammar
++input.y:6.11-13: warning: rule useless in grammar [-Wother]
+  useless1: '1';
+            ^^^
 -input.y:8.11-13: warning: rule useless in grammar
++input.y:7.11-13: warning: rule useless in grammar [-Wother]
+  useless2: '2';
+            ^^^
 -input.y:9.11-13: warning: rule useless in grammar
++input.y:8.11-13: warning: rule useless in grammar [-Wother]
+  useless3: '3';
+            ^^^
 -input.y:10.11-13: warning: rule useless in grammar
++input.y:9.11-13: warning: rule useless in grammar [-Wother]
+  useless4: '4';
+            ^^^
 -input.y:11.11-13: warning: rule useless in grammar
++input.y:10.11-13: warning: rule useless in grammar [-Wother]
+  useless5: '5';
+            ^^^
 -input.y:12.11-13: warning: rule useless in grammar
++input.y:11.11-13: warning: rule useless in grammar [-Wother]
+  useless6: '6';
+            ^^^
 -input.y:13.11-13: warning: rule useless in grammar
++input.y:12.11-13: warning: rule useless in grammar [-Wother]
+  useless7: '7';
+            ^^^
 -input.y:14.11-13: warning: rule useless in grammar
++input.y:13.11-13: warning: rule useless in grammar [-Wother]
+  useless8: '8';
+            ^^^
++input.y:14.11-13: warning: rule useless in grammar [-Wother]
+  useless9: '9';
+            ^^^
+ ]])
  AT_BISON_CHECK([[input.y]], 0, [],
 -[[input.y: warning: 9 nonterminals useless in grammar
 -input.y: warning: 9 rules useless in grammar
 -input.y:6.1-8: warning: nonterminal useless in grammar: useless1
 -input.y:7.1-8: warning: nonterminal useless in grammar: useless2
 -input.y:8.1-8: warning: nonterminal useless in grammar: useless3
 -input.y:9.1-8: warning: nonterminal useless in grammar: useless4
 -input.y:10.1-8: warning: nonterminal useless in grammar: useless5
 -input.y:11.1-8: warning: nonterminal useless in grammar: useless6
 -input.y:12.1-8: warning: nonterminal useless in grammar: useless7
 -input.y:13.1-8: warning: nonterminal useless in grammar: useless8
 -input.y:14.1-8: warning: nonterminal useless in grammar: useless9
 -input.y:6.11-13: warning: rule useless in grammar: useless1: '1'
 -input.y:7.11-13: warning: rule useless in grammar: useless2: '2'
 -input.y:8.11-13: warning: rule useless in grammar: useless3: '3'
 -input.y:9.11-13: warning: rule useless in grammar: useless4: '4'
 -input.y:10.11-13: warning: rule useless in grammar: useless5: '5'
 -input.y:11.11-13: warning: rule useless in grammar: useless6: '6'
 -input.y:12.11-13: warning: rule useless in grammar: useless7: '7'
 -input.y:13.11-13: warning: rule useless in grammar: useless8: '8'
 -input.y:14.11-13: warning: rule useless in grammar: useless9: '9'
 +[[input.y: warning: 9 nonterminals useless in grammar [-Wother]
 +input.y: warning: 9 rules useless in grammar [-Wother]
 +input.y:6.1-8: warning: nonterminal useless in grammar: useless1 [-Wother]
 +input.y:7.1-8: warning: nonterminal useless in grammar: useless2 [-Wother]
 +input.y:8.1-8: warning: nonterminal useless in grammar: useless3 [-Wother]
 +input.y:9.1-8: warning: nonterminal useless in grammar: useless4 [-Wother]
 +input.y:10.1-8: warning: nonterminal useless in grammar: useless5 [-Wother]
 +input.y:11.1-8: warning: nonterminal useless in grammar: useless6 [-Wother]
 +input.y:12.1-8: warning: nonterminal useless in grammar: useless7 [-Wother]
 +input.y:13.1-8: warning: nonterminal useless in grammar: useless8 [-Wother]
 +input.y:14.1-8: warning: nonterminal useless in grammar: useless9 [-Wother]
 +input.y:6.11-13: warning: rule useless in grammar: useless1: '1' [-Wother]
 +input.y:7.11-13: warning: rule useless in grammar: useless2: '2' [-Wother]
 +input.y:8.11-13: warning: rule useless in grammar: useless3: '3' [-Wother]
 +input.y:9.11-13: warning: rule useless in grammar: useless4: '4' [-Wother]
 +input.y:10.11-13: warning: rule useless in grammar: useless5: '5' [-Wother]
 +input.y:11.11-13: warning: rule useless in grammar: useless6: '6' [-Wother]
 +input.y:12.11-13: warning: rule useless in grammar: useless7: '7' [-Wother]
 +input.y:13.11-13: warning: rule useless in grammar: useless8: '8' [-Wother]
 +input.y:14.11-13: warning: rule useless in grammar: useless9: '9' [-Wother]
  ]])
  
  AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
@@@ -238,14 -297,34 +297,34 @@@ non_productive: non_productive useless_
  %%
  ]])
  
 -[[not-reduced.y: warning: 2 nonterminals useless in grammar
 -not-reduced.y: warning: 3 rules useless in grammar
 -not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable
+ AT_BISON_CHECK([[-fcaret not-reduced.y]], 0, [],
 -not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive
++[[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
++not-reduced.y: warning: 3 rules useless in grammar [-Wother]
++not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
+  not_reachable: useful  { /* A not reachable action. */ }
+  ^^^^^^^^^^^^^
 -not-reduced.y:11.6-57: warning: rule useless in grammar
++not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
+     | non_productive    { /* A non productive action. */ }
+       ^^^^^^^^^^^^^^
 -not-reduced.y:14.16-56: warning: rule useless in grammar
++not-reduced.y:11.6-57: warning: rule useless in grammar [-Wother]
+     | non_productive    { /* A non productive action. */ }
+       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 -not-reduced.y:17.17-18.63: warning: rule useless in grammar
++not-reduced.y:14.16-56: warning: rule useless in grammar [-Wother]
+  not_reachable: useful  { /* A not reachable action. */ }
+                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
++not-reduced.y:17.17-18.63: warning: rule useless in grammar [-Wother]
+  non_productive: non_productive useless_token
+                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ]])
  AT_BISON_CHECK([[not-reduced.y]], 0, [],
 -[[not-reduced.y: warning: 2 nonterminals useless in grammar
 -not-reduced.y: warning: 3 rules useless in grammar
 -not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable
 -not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive
 -not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive
 -not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful
 -not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token
 +[[not-reduced.y: warning: 2 nonterminals useless in grammar [-Wother]
 +not-reduced.y: warning: 3 rules useless in grammar [-Wother]
 +not-reduced.y:14.1-13: warning: nonterminal useless in grammar: not_reachable [-Wother]
 +not-reduced.y:11.6-19: warning: nonterminal useless in grammar: non_productive [-Wother]
 +not-reduced.y:11.6-57: warning: rule useless in grammar: exp: non_productive [-Wother]
 +not-reduced.y:14.16-56: warning: rule useless in grammar: not_reachable: useful [-Wother]
 +not-reduced.y:17.17-18.63: warning: rule useless in grammar: non_productive: non_productive useless_token [-Wother]
  ]])
  
  AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
index 769142008eda10acee2b8a347434a2312f9f9bc8,db6c3b9f03c5bba5f70f101e663a1a4d2b635824..c08059e5e4226d958077821b9b41048ad90016e7
@@@ -478,9 -478,17 +478,17 @@@ AT_BISON_OPTION_POPDEF
  # C-string literal.  Also notice that unnecessary escaping, such as "\?", from
  # the user specification is eliminated.
  AT_BISON_CHECK([-o input.c input.y], [[0]], [[]],
 -[[input.y:22.8-14: warning: symbol SPECIAL redeclared
 -input.y:22.8-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used more than once as a literal string
 +[[input.y:22.8-14: warning: symbol SPECIAL redeclared [-Wother]
 +input.y:22.8-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used more than once as a literal string [-Wother]
  ]])
 -[[input.y:22.8-14: warning: symbol SPECIAL redeclared
+ AT_BISON_CHECK([-fcaret -o input.c input.y], [[0]], [[]],
 -input.y:22.8-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used more than once as a literal string
++[[input.y:22.8-14: warning: symbol SPECIAL redeclared [-Wother]
+  %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
+         ^^^^^^^
++input.y:22.8-63: warning: symbol "\\'?\"\a\b\f\n\r\t\v\001\201\001\201??!" used more than once as a literal string [-Wother]
+  %token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
+         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ ]])
  AT_COMPILE([input])
  
  # Checking the error message here guarantees that yytname, which does contain