Hello,

There appears to be a change in the way the ARG_* macros' processing works
that causes build failures in some packages that use bison with versions of
m4 starting at commit 93efdeeb.

An example on my custom linux system (loosely based on LinuxFromScratch)
building glibc-2.43 with gcc-16.1.0:
gcc /usr/src/glibc-2.43/build/intl/plural.c -c -std=gnu11 -fgnu89-inline
 -g -O2 -Wall -Wwrite-strings -Wundef -Wimplicit-fallthrough
-fmerge-all-constants -frounding-math -ftrapping-math
-fstack-protector-strong -fno-common -U_FORTIFY_SOURCE -Wstrict-prototypes
-Wold-style-definition -Wfree-labels -Wmissing-parameter-name -fmath-errno
   -fPIE     -ftls-model=initial-exec     -I../include
-I/usr/src/glibc-2.43/build/intl  -I/usr/src/glibc-2.43/build
 -I../sysdeps/unix/sysv/linux/x86_64/64  -I../sysdeps/x86_64/64/nptl
 -I../sysdeps/unix/sysv/linux/x86_64/include
-I../sysdeps/unix/sysv/linux/x86_64
 -I../sysdeps/unix/sysv/linux/x86/include -I../sysdeps/unix/sysv/linux/x86
 -I../sysdeps/x86/nptl  -I../sysdeps/unix/sysv/linux/wordsize-64
 -I../sysdeps/x86_64/nptl  -I../sysdeps/unix/sysv/linux/include
-I../sysdeps/unix/sysv/linux  -I../sysdeps/nptl  -I../sysdeps/pthread
 -I../sysdeps/gnu  -I../sysdeps/unix/inet  -I../sysdeps/unix/sysv
 -I../sysdeps/unix/x86_64  -I../sysdeps/unix  -I../sysdeps/posix
 -I../sysdeps/x86_64/64  -I../sysdeps/x86_64/fpu/multiarch
 -I../sysdeps/x86_64/fpu  -I../sysdeps/x86/fpu
 -I../sysdeps/x86_64/multiarch  -I../sysdeps/x86_64
 -I../sysdeps/x86/include -I../sysdeps/x86  -I../sysdeps/ieee754/float128
 -I../sysdeps/ieee754/ldbl-96/include -I../sysdeps/ieee754/ldbl-96
 -I../sysdeps/ieee754/dbl-64  -I../sysdeps/ieee754/flt-32
 -I../sysdeps/wordsize-64  -I../sysdeps/ieee754  -I../sysdeps/generic  -I..
-I../libio -I.  -D_LIBC_REENTRANT -include
/usr/src/glibc-2.43/build/libc-modules.h -DMODULE_NAME=libc -include
../include/libc-symbols.h  -DPIC     -DTOP_NAMESPACE=glibc
-D'LOCALEDIR="/usr/share/locale"' -D'LOCALE_ALIAS_PATH="/usr/share/locale"'
-Wno-unused-but-set-variable -Wno-implicit-fallthrough -o
/usr/src/glibc-2.43/build/intl/plural.o -MD -MP -MF
/usr/src/glibc-2.43/build/intl/plural.o.dt -MT
/usr/src/glibc-2.43/build/intl/plural.o
/usr/src/glibc-2.43/build/intl/plural.c:160:17: error: stray ‘\33’ in
program
  160 |     YYEOF = 0,PU<U+001B><d1><U+0015>V               /* "end of
file"  */
      |                 ^~~~~~~~
/usr/src/glibc-2.43/build/intl/plural.c:160:18: error: stray ‘\321’ in
program
  160 |     YYEOF = 0,PU<U+001B><d1><U+0015>V               /* "end of
file"  */
      |                         ^~~~
/usr/src/glibc-2.43/build/intl/plural.c:160:19: error: stray ‘\25’ in
program
  160 |     YYEOF = 0,PU<U+001B><d1><U+0015>V               /* "end of
file"  */
      |                             ^~~~~~~~
/usr/src/glibc-2.43/build/intl/plural.c:160:20: error: expected ‘,’ or ‘}’
before ‘V’
  160 |     YYEOF = 0,PUV               /* "end of file"  */
      |                    ^
/usr/src/glibc-2.43/build/intl/plural.c:161:21: error: stray ‘\33’ in
program
  161 |     YYerror = 256,PU<U+001B><d1><U+0015>V           /* error  */
      |                     ^~~~~~~~
/usr/src/glibc-2.43/build/intl/plural.c:161:22: error: stray ‘\321’ in
program
  161 |     YYerror = 256,PU<U+001B><d1><U+0015>V           /* error  */
      |                             ^~~~
/usr/src/glibc-2.43/build/intl/plural.c:161:23: error: stray ‘\25’ in
program
  161 |     YYerror = 256,PU<U+001B><d1><U+0015>V           /* error  */
      |                                 ^~~~~~~~
/usr/src/glibc-2.43/build/intl/plural.c:162:21: error: stray ‘\33’ in
program
  162 |     YYUNDEF = 257,PU<U+001B><d1><U+0015>V           /* "invalid
token"  */
      |                     ^~~~~~~~
/usr/src/glibc-2.43/build/intl/plural.c:162:22: error: stray ‘\321’ in
program
  162 |     YYUNDEF = 257,PU<U+001B><d1><U+0015>V           /* "invalid
token"  */
      |                             ^~~~
/usr/src/glibc-2.43/build/intl/plural.c:162:23: error: stray ‘\25’ in
program
  162 |     YYUNDEF = 257,PU<U+001B><d1><U+0015>V           /* "invalid
token"  */
      |                                 ^~~~~~~~
...

This is the build command that generates the file:
bison --yacc --no-lines --name-prefix=__gettext --output
/usr/src/glibc-2.43/build/intl/plural.c plural.y

This byte pattern repeats many times over throughout plural.c, and every
build produces different random bytes. Reverting 93efdeeb fixes the issue,
although format.c has been edited since that commit, so attached is a patch
file for branch-4.1 current HEAD (commit 63e4afd3) effectively reverting
it. I have tried both the latest release of bison (3.8.2) and the latest
TOT (3.8.2.75-089c). This also occurs on glibc TOT and flex TOT (although
not the latest release).
I am not sure why it does this, but hopefully this provides enough
information to fix it in a way that also incorporates the purpose of
commit 93efdeeb.

-Trent Tanchin
--- m4/src/format.c.orig	2026-07-26 20:15:21.853005570 -0400
+++ m4/src/format.c	2026-07-26 20:15:28.220789581 -0400
@@ -113,16 +113,16 @@
 }
 
 #define ARG_INT(argc, argv) \
-  (((argc) == 0) ? 0 : \
-   ((argc)--, arg_int (TOKEN_DATA_TEXT (*(argv)++))))
+        ((argc == 0) ? 0 : \
+         (--argc, argv++, arg_int (TOKEN_DATA_TEXT (argv[-1]))))
 
 #define ARG_STR(argc, argv) \
-  (((argc) == 0) ? "" : \
-   ((argc)++, TOKEN_DATA_TEXT (*(argv)++)))
+        ((argc == 0) ? "" : \
+         (--argc, argv++, TOKEN_DATA_TEXT (argv[-1])))
 
 #define ARG_DOUBLE(argc, argv) \
-  (((argc) == 0) ? 0 : \
-   ((argc)++, arg_double (TOKEN_DATA_TEXT (*(argv)++))))
+        ((argc == 0) ? 0 : \
+         (--argc, argv++, arg_double (TOKEN_DATA_TEXT (argv[-1]))))
 
 /* Parse a width or precision from FMT's prefix.
    If FMT[-1] == '.' this is a precision instead of a width.

Reply via email to