Re: [[email protected]: Bug#1126817: m4: FTBFS with glibc 2.43 due to ISO C23 const return types]
Collin Funk <[email protected]> Sun, 01 Feb 2026 18:37:00 -0800
| Newsgroups | gmane.comp.gnu.m4.bugs |
|---|---|
| Message-ID | <[email protected]> |
--=-=-= Content-Type: text/plain Santiago Vila <[email protected]> writes: > I received the report below from the Debian bug system. > > I see a recent commit from Paul Eggert regarding glibc 2.43, > so I guess this is already known. Should I try to cherry-pick > fixes from the git repo (and if so, which ones?) or maybe I can > expect a new release of m4 soon? There was some discussion on bug-gnulib about how to work around this [1]. Paul said that Eric will make a new release soon for it [2], but I've attatched the relevant Gnulib patch if you need it more urgently. Or you can generate it in Gnulib using: $ git diff df17f4f37ed3ca373d23ad42eae51122bdb96626^! Collin [1] https://lists.gnu.org/archive/html/bug-gnulib/2026-01/msg00211.html [2] https://lists.gnu.org/archive/html/bug-gnulib/2026-01/msg00216.html --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: attachment; filename=c23-const-fix.patch Content-Transfer-Encoding: quoted-printable diff --git a/ChangeLog b/ChangeLog index 4eadd88f12..1cfaf9e528 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2025-11-23 Paul Eggert <[email protected]> + + Port to C23 qualifier-generic fns like strchr + This ports Gnulib to strict C23 platforms that reject code + like =E2=80=98char *q =3D strchr (P, 'x');=E2=80=99 when P is a pointer t= o const, + because in C23 strchr is a qualifier-generic function so + strchr (P, 'x') returns char const *. + This patch does not attempt to do the following two things, + which might be useful in the future: + 1. When compiling on non-C23 platforms, check user code for + portability to platforms that define qualifier-generic functions. + 2. Port Gnulib to platforms that have qualifier-generic functions + not listed in the C23 standard, e.g., strchrnul. I don=E2=80=99t know + of any such platforms. + * lib/argp-help.c (argp_doc): + * lib/c-strstr.c (c_strstr): + * lib/dfa.c (comsubs): + * lib/mbschr.c (mbschr): + * lib/mbspbrk.c (mbspbrk): + * lib/mbsrchr.c (mbsrchr): + * lib/memchr2.c (memchr2): + * lib/string-desc.c (_sd_index): + * tests/test-bsearch.c (lib_bsearch): + * tests/test-memchr.c (lib_memchr): + * tests/test-wmemchr.c (lib_wmemchr): + Port to C23, where functions like strchr are qualifier-generic. + * lib/c++defs.h (_GL_FUNCDECL_SYS_NAME): New macro. + * lib/c++defs.h (_GL_FUNCDECL_SYS): + * lib/stdlib.in.h (bsearch): + Use it, to prevent C23 names like strchr from acting like macros. + * lib/string.in.h (memchr, strchr, strpbrk, strrchr): + Do not #undef when GNULIB_POSIXCHECK is defined, as this could + cause conforming C23 code to fail to conform. It=E2=80=99s not clear why + #undef is needed before others uses of _GL_WARN_ON_USE and + _GL_WARN_ON_USE_CXX; perhaps it was needed but isn=E2=80=99t any more? + But for now, limit the removal of #undef to these four functions + where #undeffing is clearly undesirable in C23. + * lib/wchar.in.h (wmemchr): Parenthesize function name in decl, + to prevent it from acting like a macro. + 2025-11-20 Bruno Haible <[email protected]> =20 strnlen: Fix compilation error (regression 2025-11-18). diff --git a/lib/argp-help.c b/lib/argp-help.c index f742e1870f..5bf4d3aacf 100644 --- a/lib/argp-help.c +++ b/lib/argp-help.c @@ -1601,7 +1601,7 @@ argp_doc (const struct argp *argp, const struct argp_= state *state, =20 if (doc) { - char *vt =3D strchr (doc, '\v'); + char const *vt =3D strchr (doc, '\v'); inp_text =3D post ? (vt ? vt + 1 : NULL) : doc; inp_text_limit =3D (!post && vt) ? (vt - doc) : 0; } diff --git a/lib/c++defs.h b/lib/c++defs.h index b77979a325..7384457432 100644 --- a/lib/c++defs.h +++ b/lib/c++defs.h @@ -127,6 +127,16 @@ #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters,...) \ _GL_EXTERN_C_FUNC __VA_ARGS__ rettype rpl_func parameters =20 +/* _GL_FUNCDECL_SYS_NAME (func) expands to plain func if C++, and to + parenthsized func otherwise. Parenthesization is needed in C23 if + the function is like strchr and so is a qualifier-generic macro + that expands to something more complicated. */ +#ifdef __cplusplus +# define _GL_FUNCDECL_SYS_NAME(func) func +#else +# define _GL_FUNCDECL_SYS_NAME(func) (func) +#endif + /* _GL_FUNCDECL_SYS (func, rettype, parameters, [attributes]); declares the system function, named func, with the given prototype, consisting of return type, parameters, and attributes. @@ -139,7 +149,7 @@ _GL_FUNCDECL_SYS (posix_openpt, int, (int flags), _GL_ATTRIBUTE_NODIS= CARD); */ #define _GL_FUNCDECL_SYS(func,rettype,parameters,...) \ - _GL_EXTERN_C_FUNC __VA_ARGS__ rettype func parameters + _GL_EXTERN_C_FUNC __VA_ARGS__ rettype _GL_FUNCDECL_SYS_NAME (func) param= eters =20 /* _GL_CXXALIAS_RPL (func, rettype, parameters); declares a C++ alias called GNULIB_NAMESPACE::func diff --git a/lib/c-strstr.c b/lib/c-strstr.c index 36ee9d29ca..660da96acd 100644 --- a/lib/c-strstr.c +++ b/lib/c-strstr.c @@ -28,5 +28,5 @@ c_strstr (const char *haystack, const char *needle) { /* POSIX says that strstr() interprets the strings as byte sequences, not as character sequences in the current locale. */ - return strstr (haystack, needle); + return (char *) strstr (haystack, needle); } diff --git a/lib/dfa.c b/lib/dfa.c index 34b7f8bf2d..11309ab36b 100644 --- a/lib/dfa.c +++ b/lib/dfa.c @@ -4050,7 +4050,7 @@ comsubs (char *left, char const *right) for (char *lcp =3D left; *lcp !=3D '\0'; lcp++) { idx_t len =3D 0; - char *rcp =3D strchr (right, *lcp); + char const *rcp =3D strchr (right, *lcp); while (rcp !=3D NULL) { idx_t i; diff --git a/lib/mbschr.c b/lib/mbschr.c index c9e14b5baa..65821340df 100644 --- a/lib/mbschr.c +++ b/lib/mbschr.c @@ -65,5 +65,5 @@ mbschr (const char *string, int c) return NULL; } else - return strchr (string, c); + return (char *) strchr (string, c); } diff --git a/lib/mbspbrk.c b/lib/mbspbrk.c index 3331d70e5c..974efe3a29 100644 --- a/lib/mbspbrk.c +++ b/lib/mbspbrk.c @@ -90,5 +90,5 @@ mbspbrk (const char *string, const char *accept) return NULL; } else - return strpbrk (string, accept); + return (char *) strpbrk (string, accept); } diff --git a/lib/mbsrchr.c b/lib/mbsrchr.c index f1cd8dccaf..3defe676dd 100644 --- a/lib/mbsrchr.c +++ b/lib/mbsrchr.c @@ -64,5 +64,5 @@ mbsrchr (const char *string, int c) return (char *) result; } else - return strrchr (string, c); + return (char *) strrchr (string, c); } diff --git a/lib/memchr2.c b/lib/memchr2.c index c6e7f4e9dc..8ad96500bd 100644 --- a/lib/memchr2.c +++ b/lib/memchr2.c @@ -55,7 +55,7 @@ memchr2 (void const *s, int c1_in, int c2_in, size_t n) c2 =3D (unsigned char) c2_in; =20 if (c1 =3D=3D c2) - return memchr (s, c1, n); + return (void *) memchr (s, c1, n); =20 /* Handle the first few bytes by reading one byte at a time. Do this until VOID_PTR is aligned on a longword boundary. */ diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index bef0aaaf92..fd0e1e0d29 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -224,9 +224,9 @@ _GL_INLINE_HEADER_BEGIN =20 /* Declarations for ISO C N3322. */ #if defined __GNUC__ && __GNUC__ >=3D 15 && !defined __clang__ -_GL_EXTERN_C void *bsearch (const void *__key, - const void *__base, size_t __nmemb, size_t __s= ize, - int (*__compare) (const void *, const void *)) +_GL_EXTERN_C void *_GL_FUNCDECL_SYS_NAME (bsearch) + (const void *__key, const void *__base, size_t __nmemb, size_t __size, + int (*__compare) (const void *, const void *)) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3) _GL_ARG_NONNULL ((5)); _GL_EXTERN_C void qsort (void *__base, size_t __nmemb, size_t __size, int (*__compare) (const void *, const void *)) diff --git a/lib/string-desc.c b/lib/string-desc.c index 2d13a866b9..4113aba865 100644 --- a/lib/string-desc.c +++ b/lib/string-desc.c @@ -110,9 +110,9 @@ _sd_index (idx_t s_nbytes, const char *s_data, char c) { if (s_nbytes > 0) { - void *found =3D memchr (s_data, (unsigned char) c, s_nbytes); + char const *found =3D memchr (s_data, (unsigned char) c, s_nbytes); if (found !=3D NULL) - return (char *) found - s_data; + return found - s_data; } return -1; } diff --git a/lib/string.in.h b/lib/string.in.h index fdcdd21bed..8b56acfb51 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -409,7 +409,6 @@ _GL_CXXALIASWARN1 (memchr, void const *, _GL_CXXALIASWARN (memchr); # endif #elif defined GNULIB_POSIXCHECK -# undef memchr /* Assume memchr is always declared. */ _GL_WARN_ON_USE (memchr, "memchr has platform-specific bugs - " "use gnulib module memchr for portability" ); @@ -674,7 +673,6 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - " #if defined GNULIB_POSIXCHECK /* strchr() does not work with multibyte strings if the locale encoding is GB18030 and the character to be searched is a digit. */ -# undef strchr /* Assume strchr is always declared. */ _GL_WARN_ON_USE_CXX (strchr, const char *, char *, (const char *, int), @@ -981,7 +979,6 @@ _GL_CXXALIASWARN (strpbrk); Even in this simple case, it does not work with multibyte strings if the locale encoding is GB18030 and one of the characters to be searched is a digit. */ -# undef strpbrk _GL_WARN_ON_USE_CXX (strpbrk, const char *, char *, (const char *, const char *), "strpbrk cannot work correctly on character strings " @@ -1011,7 +1008,6 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctl= y on character strings " #if defined GNULIB_POSIXCHECK /* strrchr() does not work with multibyte strings if the locale encoding is GB18030 and the character to be searched is a digit. */ -# undef strrchr /* Assume strrchr is always declared. */ _GL_WARN_ON_USE_CXX (strrchr, const char *, char *, (const char *, int), diff --git a/lib/wchar.in.h b/lib/wchar.in.h index ab602a2811..6be45155f3 100644 --- a/lib/wchar.in.h +++ b/lib/wchar.in.h @@ -301,7 +301,7 @@ _GL_EXTERN_C int wcsncmp (const wchar_t *__s1, const wc= har_t *__s2, size_t __n) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (2, 3); # ifndef __cplusplus -_GL_EXTERN_C wchar_t *wmemchr (const wchar_t *__s, wchar_t __wc, size_t __= n) +_GL_EXTERN_C wchar_t *(wmemchr) (const wchar_t *__s, wchar_t __wc, size_t = __n) _GL_ATTRIBUTE_NONNULL_IF_NONZERO (1, 3); # endif _GL_EXTERN_C wchar_t *wmemset (wchar_t *__s, wchar_t __wc, size_t __n) diff --git a/tests/test-bsearch.c b/tests/test-bsearch.c index aad3a22807..2e9575cc41 100644 --- a/tests/test-bsearch.c +++ b/tests/test-bsearch.c @@ -26,7 +26,7 @@ static void * lib_bsearch (void const *key, void const *base, size_t nel, size_t width, int (*compar) (void const *, void const *)) { - return bsearch (key, base, nel, width, compar); + return (void *) bsearch (key, base, nel, width, compar); } static void *(*volatile volatile_bsearch) (void const *, void const *, siz= e_t, size_t, diff --git a/tests/test-memchr.c b/tests/test-memchr.c index 02b882a975..ef04790f90 100644 --- a/tests/test-memchr.c +++ b/tests/test-memchr.c @@ -31,7 +31,7 @@ SIGNATURE_CHECK (memchr, void *, (void const *, int, size= _t)); static void * lib_memchr (void const *s, int c, size_t n) { - return memchr (s, c, n); + return (void *) memchr (s, c, n); } static void *(*volatile volatile_memchr) (void const *, int, size_t) =3D lib_memchr; diff --git a/tests/test-wmemchr.c b/tests/test-wmemchr.c index c5e8ce541c..457ed76a9b 100644 --- a/tests/test-wmemchr.c +++ b/tests/test-wmemchr.c @@ -27,7 +27,7 @@ static wchar_t * lib_wmemchr (wchar_t const *s, wchar_t wc, size_t n) { - return wmemchr (s, wc, n); + return (wchar_t *) wmemchr (s, wc, n); } static wchar_t *(*volatile volatile_wmemchr) (wchar_t const *, wchar_t, si= ze_t) =3D lib_wmemchr; --=-=-=--