[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: string.h on rhES 7
From: |
Bruno Haible |
Subject: |
Re: string.h on rhES 7 |
Date: |
Sat, 30 Apr 2022 14:10:04 +0200 |
Tom Tromey wrote:
> Hi. gdb recently updated gnulib to
>
> GNULIB_COMMIT_SHA1="0cda5beb7962f6567f0c4e377df870fa05c6d681"
>
> This caused a build failure here at AdaCore, where we are using a
> relatively recent GCC (11.2) on an rhES 7 host:
>
> CC libgnu_a-openat-proc.o
> In file included from /usr/include/string.h:633,
> from ./string.h:41,
> from ../../../binutils-gdb/gnulib/import/openat-proc.c:30:
> ./string.h:1105:1: error: expected identifier or '(' before '__extension__'
> 1105 | _GL_FUNCDECL_SYS (strndup, char *,
> | ^~~~~~~~~~~~~~~~
>
> We worked around this locally by reverting gnulib commit cbdb5ea63.
>
> Today I looked into it a bit more and found that, after preprocessing,
> the line in question looks like:
>
> extern char * (__extension__ (__builtin_constant_p (char const *__s) &&
> ((size_t)(const void *)((char const *__s) + 1) - (size_t)(const void *)(char
> const *__s) == 1) ? (((const char *) (char const *__s))[0] == '\0' ? (char *)
> calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (char const *__s)
> + 1; size_t __n = (size_t __n); char *__retval; if (__n < __len) __len = __n
> + 1; __retval = (char *) malloc (__len); if (__retval != ((void *)0)) {
> __retval[__len - 1] = '\0'; __retval = (char *) memcpy (__retval, char const
> *__s, __len - 1); } __retval; })) : __strndup (char const *__s, size_t __n)))
> __attribute__ ((__nonnull__ (1)))
>
>
> That is, there's an unexpected macro expansion coming from glibc:
>
> # 1314 "/usr/include/bits/string2.h" 3 4
> [...]
> #define __strndup(s,n) (__extension__ (__builtin_constant_p (s) &&
> __string2_1bptr_p (s) ? (((const char *) (s))[0] == '\0' ? (char *) calloc
> ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (s) + 1; size_t __n =
> (n); char *__retval; if (__n < __len) __len = __n + 1; __retval = (char *)
> malloc (__len); if (__retval != NULL) { __retval[__len - 1] = '\0'; __retval
> = (char *) memcpy (__retval, s, __len - 1); } __retval; })) : __strndup (s,
> n)))
> # 1342 "/usr/include/bits/string2.h" 3 4
> #define strndup(s,n) __strndup (s, n)
Thanks for the report and the details; that explains it. It occurs only
with a glibc from 2017 or older, in combination with GCC 11 or newer.
> I'm not 100% sure of the best way to fix this in gnulib, as I'm not
> familiar with all the ins and outs of working on it, but I can report
> that the appended works.
There are two possible fixes:
- #undef strndup. This reverts the optimization done in the glibc headers.
- Omit the redeclaration line if strndup is a macro. This is less intrusive.
Since the expansion invokes calloc, malloc, or __strndup, and the first two
are already associated with free or rpl_free. In the worst case, you may
get a warning about a use of __strndup. But since most people who use a
GCC ≥ 11 also use a recent glibc, I think this is bearable.
2022-04-30 Bruno Haible <bruno@clisp.org>
string: Avoid syntax error on glibc systems with GCC 11.
Reported by Tom Tromey <tromey@adacore.com> in
<https://lists.gnu.org/archive/html/bug-gnulib/2022-04/msg00075.html>
and by Satadru Pramanik <satadru@umich.edu> in
<https://lists.gnu.org/archive/html/bug-gnulib/2022-04/msg00076.html>.
* lib/string.in.h (strndup): Don't rededeclare strndup if it is defined
as a macro.
diff --git a/lib/string.in.h b/lib/string.in.h
index b6840fa912..33160b2525 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -583,7 +583,7 @@ _GL_FUNCDECL_RPL (strndup, char *,
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE);
_GL_CXXALIAS_RPL (strndup, char *, (char const *__s, size_t __n));
# else
-# if !@HAVE_DECL_STRNDUP@ || __GNUC__ >= 11
+# if !@HAVE_DECL_STRNDUP@ || (__GNUC__ >= 11 && !defined strndup)
_GL_FUNCDECL_SYS (strndup, char *,
(char const *__s, size_t __n)
_GL_ARG_NONNULL ((1))
@@ -593,7 +593,7 @@ _GL_CXXALIAS_SYS (strndup, char *, (char const *__s, size_t
__n));
# endif
_GL_CXXALIASWARN (strndup);
#else
-# if __GNUC__ >= 11
+# if __GNUC__ >= 11 && !defined strndup
/* For -Wmismatched-dealloc: Associate strndup with free or rpl_free. */
_GL_FUNCDECL_SYS (strndup, char *,
(char const *__s, size_t __n)