Subject: Re: [bison-3.8] bug or side effect to flex & automake

From: Akim Demaille <[email-masked]>
Date: Wed, 8 Sep 2021 07:31:28 +0200

Hi Kiyoshi,

> Le 8 sept. 2021 à 04:11, Kiyoshi KANAZAWA <[email-masked]> a écrit :
> 
> Hello,
> 
> Installed bison-3.8, but I'm afraid it is has bug or side effect to flex-2.6.4 & automake-1.16.4.
> 
> $ uname -a
> SunOS hidden 5.11 11.3 i86pc i386 i86pc
> 
> $ gcc --version
> gcc (GCC) 10.3.0
> 
> After installing bison-3.8, detected the following make check error, which did not with bison-3.7.6.
> 
> (1) flex-2.6.4
> mv -f $depbase.Tpo $depbase.Po
> depbase=`echo bison_nr_parser.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
> gcc -m32 -DHAVE_CONFIG_H -I. -I../src  -I../src -I../src    -MT bison_nr_parser.o -MD -MP -MF $depbase.Tpo -c -o bison_nr_parser.o bison_nr_parser.c &&\
> mv -f $depbase.Tpo $depbase.Po
> bison_nr_parser.c:70:25: error: conflicting types for 'testerror'
>    70 | #define yyerror         testerror
>       |                         ^~~~~~~~~
> bison_nr_parser.y:40:5: note: in expansion of macro 'yyerror'
>    40 | int yyerror(const char* msg);
>       |     ^~~~~~~
> In file included from bison_nr_parser.y:33:
> bison_nr_parser.h:110:6: note: previous declaration of 'testerror' was here
>   110 | void testerror (const YYLTYPE *yyllocp, const char *msg);
>       |      ^~~~~~~~~
> bison_nr_parser.c:70:25: error: conflicting types for 'testerror'
>    70 | #define yyerror         testerror
>       |                         ^~~~~~~~~
> bison_nr_parser.y:93:5: note: in expansion of macro 'yyerror'
>    93 | int yyerror(const char* msg) {
>       |     ^~~~~~~
> In file included from bison_nr_parser.y:33:
> bison_nr_parser.h:110:6: note: previous declaration of 'testerror' was here
>   110 | void testerror (const YYLTYPE *yyllocp, const char *msg);
>       |      ^~~~~~~~~
> make[2]: *** [Makefile:2076: bison_nr_parser.o] Error 1
> 
> And so on.

Well, I'm afraid this change was made on purpose, to conform with the (unfortunate IMHO) latest specs of POSIX Yacc.  See the NEWS file:

  To comply with the latest POSIX standard, in Yacc compatibility mode
  (options `-y`/`--yacc`) Bison now generates prototypes for yyerror and
  yylex.  In some situations, this is breaking compatibility: if the user
  has already declared these functions but with some differences (e.g., to
  declare them as static, or to use specific attributes), the generated
  parser will fail to compile.  To disable these prototypes, #define yyerror
  (to `yyerror`), and likewise for yylex.

This change in POSIX was discussed here: https://austingroupbugs.net/view.php?id=1388#c5220.  However, I don't see a published version of the POSIX Yacc "specs" that includes these changes.  The latest edition appears to be from 2018 (https://pubs.opengroup.org/onlinepubs/9699919799/).

That being said, several tests can be easily adjusted.  For instance t/silent-yacc fails because it provides this implementation of yyerror:

void yyerror (char *s) { return; }

while the expected signature is

void yyerror (const char *s);

I have not checked all the tests, but I suspect that many of them can be easily fixed.

I don't see you, Kiyoshi, in the logs of Automake, so I suppose you are not maintaining/contributing to Automake.  Yet we need to fix these tests (I'd be happy to get feedback from Automake's team on this).

This is definitely a change that may break compatibility in some cases, but it's out of our control: POSIX decided, we just comply.  One big problem with the Autotools as of today is that they promote the use of macros/build rules for Yacc, not for Bison.  Because of this, bison is almost always called with `-y/--yacc`, which not only forces bison to generate y.tab.c instead of foo.tab.c, but also forces it to enter the POSIX Yacc mode (and also to spit tons of warnings for each GNU Bison feature which is not part of POSIX Yacc).

Cheers!