openwrt-pf/tools/gnulib/patches/400-c23-qualifier-generic.patch
Michael Pratt a3830a1589 tools: gnulib: fix build with latest glibc C23 changes
Backport a patch that covers a build problem with latest glibc
being used as the host standard C library during tools build.

The C23 standard changes some functions that used to drop qualifiers
like "const" or "volatile" and are now forced to preserve them
in the return type based on the input type at all times.
Developers of glibc have responded by making these functions
into macros after they are declared with prototypes.
This is not compatible with the way gnulib is written,
so when the functions are redeclared in gnulib,
the preprocessor expands the _function name_ itself
as if it is a macro name, but not fully,
which results in unusual looking build errors,
e.g. the failed processing of keywords that were never written
and have no business being in a prototype, or,
as a keyword that is expected to be there and nearly guarenteed
to work but mysteriously is not working, displayed as:
"error: expected identifier or '(' before _____".

The backport patch introduces and implements a new macro
in order to prevent function names from being interpreted as macros,
by wrapping it in parentheses for C, or simply placing it back for C++
in the first stage of macro expansion which satisfies the goal
of no further expansion taking place during preprocessing.

Add an additional patch for the functions declared
in the fts header, as this bug also applies to them,
however, this was overlooked by upstream gnulib,
likely because the bug is not presenting as an error.

Yet another patch corrects the order between
specifiers and attributes in GCC syntax for header
lib/fts.in.h which can be blamed on an upstream commit.

Specifically, the throw() or noexcept() keywords
must be before attributes at the end of a declaration.
There are two headers, lib/cdefs.h and lib/getopt-ext.h
that already demonstrate the correct order which is very
strictly necessary in the latest version of GCC
when compiling C++ code, and acceptable for C code,
as the "__THROW" macro is simply another attribute in that case.

Added backport patch:
 - 400-c23-qualifier-generic.patch

Added pending patch:
 - 410-unmacro-fts-functions.patch
 - 450-attribute-specifier-order.patch

Ref: 80e5de158316 ("fts: Improve GCC 11 allocation-deallocation checking.") # gnulib.git
Reported-by: Aditya Nugraha <vortexilation@gmail.com>
Signed-off-by: Michael Pratt <mcpratt@pm.me>
Link: https://github.com/openwrt/openwrt/pull/24247
Signed-off-by: Robert Marko <robimarko@gmail.com>
2026-07-30 19:40:44 +02:00

266 lines
9.8 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From df17f4f37ed3ca373d23ad42eae51122bdb96626 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sun, 23 Nov 2025 00:50:40 -0800
Subject: [PATCH] Port to C23 qualifier-generic fns like strchr
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This ports Gnulib to strict C23 platforms that reject code
like char *q = strchr (P, 'x'); when P is a pointer to 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 dont 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. Its not clear why
_GL_WARN_ON_USE_CXX; perhaps it was needed but isnt 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.
---
ChangeLog | 40 ++++++++++++++++++++++++++++++++++++++++
lib/argp-help.c | 2 +-
lib/c++defs.h | 12 +++++++++++-
lib/c-strstr.c | 2 +-
lib/dfa.c | 2 +-
lib/mbschr.c | 2 +-
lib/mbspbrk.c | 2 +-
lib/mbsrchr.c | 2 +-
lib/memchr2.c | 2 +-
lib/stdlib.in.h | 6 +++---
lib/string-desc.c | 4 ++--
lib/string.in.h | 4 ----
lib/wchar.in.h | 2 +-
tests/test-bsearch.c | 2 +-
tests/test-memchr.c | 2 +-
tests/test-wmemchr.c | 2 +-
16 files changed, 67 insertions(+), 21 deletions(-)
--- a/lib/argp-help.c
+++ b/lib/argp-help.c
@@ -1601,7 +1601,7 @@ argp_doc (const struct argp *argp, const
if (doc)
{
- char *vt = strchr (doc, '\v');
+ char const *vt = strchr (doc, '\v');
inp_text = post ? (vt ? vt + 1 : NULL) : doc;
inp_text_limit = (!post && vt) ? (vt - doc) : 0;
}
--- 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
+/* _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_NODISCARD);
*/
#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) parameters
/* _GL_CXXALIAS_RPL (func, rettype, parameters);
declares a C++ alias called GNULIB_NAMESPACE::func
--- a/lib/c-strstr.c
+++ b/lib/c-strstr.c
@@ -28,5 +28,5 @@ c_strstr (const char *haystack, const ch
{
/* 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);
}
--- a/lib/dfa.c
+++ b/lib/dfa.c
@@ -4069,7 +4069,7 @@ comsubs (char *left, char const *right)
for (char *lcp = left; *lcp != '\0'; lcp++)
{
idx_t len = 0;
- char *rcp = strchr (right, *lcp);
+ char const *rcp = strchr (right, *lcp);
while (rcp != NULL)
{
idx_t i;
--- 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);
}
--- a/lib/mbspbrk.c
+++ b/lib/mbspbrk.c
@@ -90,5 +90,5 @@ mbspbrk (const char *string, const char
return NULL;
}
else
- return strpbrk (string, accept);
+ return (char *) strpbrk (string, accept);
}
--- 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);
}
--- a/lib/memchr2.c
+++ b/lib/memchr2.c
@@ -55,7 +55,7 @@ memchr2 (void const *s, int c1_in, int c
c2 = (unsigned char) c2_in;
if (c1 == c2)
- return memchr (s, c1, n);
+ return (void *) memchr (s, c1, n);
/* Handle the first few bytes by reading one byte at a time.
Do this until VOID_PTR is aligned on a longword boundary. */
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -238,9 +238,9 @@ _GL_INLINE_HEADER_BEGIN
/* Declarations for ISO C N3322. */
#if defined __GNUC__ && __GNUC__ >= 15 && !defined __clang__
-_GL_EXTERN_C void *bsearch (const void *__key,
- const void *__base, size_t __nmemb, size_t __size,
- 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 *))
--- a/lib/string-desc.c
+++ b/lib/string-desc.c
@@ -113,9 +113,9 @@ _sd_index (idx_t s_nbytes, const char *s
{
if (s_nbytes > 0)
{
- void *found = memchr (s_data, (unsigned char) c, s_nbytes);
+ char const *found = memchr (s_data, (unsigned char) c, s_nbytes);
if (found != NULL)
- return (char *) found - s_data;
+ return found - s_data;
}
return -1;
}
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -403,7 +403,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_CXX (memchr,
const void *, void *, (void const *, int, size_t),
@@ -655,7 +654,6 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is un
#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),
@@ -976,7 +974,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 "
@@ -1006,7 +1003,6 @@ _GL_WARN_ON_USE (strspn, "strspn cannot
#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),
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -316,7 +316,7 @@ _GL_EXTERN_C int wcsncmp (const wchar_t
_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)
--- 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 *, size_t,
size_t,
--- a/tests/test-memchr.c
+++ b/tests/test-memchr.c
@@ -31,7 +31,7 @@ SIGNATURE_CHECK (memchr, void *, (void c
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)
= lib_memchr;
--- 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, size_t)
= lib_wmemchr;