bug-gnulib
[Top][All Lists]
Advanced

[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)






reply via email to

[Prev in Thread] Current Thread [Next in Thread]