[1/5] misc: Sync cdefs.h with gnulib

Message ID 20210113165826.1014708-1-adhemerval.zanella@linaro.org
State Committed
Delegated to: Adhemerval Zanella Netto
Headers
Series [1/5] misc: Sync cdefs.h with gnulib |

Commit Message

Adhemerval Zanella Jan. 13, 2021, 4:58 p.m. UTC
  It adds __glibc_has_builtin, __glibc_has_extension, and
__attribute_maybe_unused__ alongsize with some fixes.

The only difference is:
  

Comments

Joseph Myers Jan. 13, 2021, 6:09 p.m. UTC | #1
On Wed, 13 Jan 2021, Adhemerval Zanella via Libc-alpha wrote:

> +#if defined __STDC_VERSION__ && 201710L < __STDC_VERSION__
> +# define __attribute_maybe_unused__ [[__maybe_unused__]]

I don't think that will work with GCC 9 -std=c2x or -std=gnu2x (support 
for [[]] attributes was added in GCC 10).  This macro isn't used at all in 
glibc, what compilers and options are expected to be supported for it in 
gnulib?

If you compare __STDC_VERSION__ with the version for the previous 
standard, and intend to support compilers such as GCC 9 -std=gnu2x, you 
need to deal with incomplete implementations using placeholder values 
(202000L in this case).  (You might have incomplete implementations even 
comparing with the final value used for C23, but they're less likely to be 
so incomplete.)

When you're supporting [[__maybe_unused__]] you might want to support it 
for C++17 as well as C2x.  Or is this macro in gnulib only intended to be 
used in C code, not C++?
  
Adhemerval Zanella Jan. 13, 2021, 6:30 p.m. UTC | #2
On 13/01/2021 15:09, Joseph Myers wrote:
> On Wed, 13 Jan 2021, Adhemerval Zanella via Libc-alpha wrote:
> 
>> +#if defined __STDC_VERSION__ && 201710L < __STDC_VERSION__
>> +# define __attribute_maybe_unused__ [[__maybe_unused__]]
> 
> I don't think that will work with GCC 9 -std=c2x or -std=gnu2x (support 
> for [[]] attributes was added in GCC 10).  This macro isn't used at all in 
> glibc, what compilers and options are expected to be supported for it in 
> gnulib?
> 
> If you compare __STDC_VERSION__ with the version for the previous 
> standard, and intend to support compilers such as GCC 9 -std=gnu2x, you 
> need to deal with incomplete implementations using placeholder values 
> (202000L in this case).  (You might have incomplete implementations even 
> comparing with the final value used for C23, but they're less likely to be 
> so incomplete.)
> 
> When you're supporting [[__maybe_unused__]] you might want to support it 
> for C++17 as well as C2x.  Or is this macro in gnulib only intended to be 
> used in C code, not C++?
> 

It is only used on C code, more specially for lib/malloc/dynarray-skeleton.c.
And I am no sure if gnulib has active support -std=c2x or -std=gnu2x and
I think Paul can give us a better idea on how to support this better on
gnulib side.
  
Paul Eggert Jan. 13, 2021, 7:19 p.m. UTC | #3
Thanks, I'll try to take a look at these.

Also, I've been trying to pry free some time to review the patches you 
proposed earlier for fnmatch and glob. I'll respond on those threads 
with what I have now. I'm assuming that those patches won't get into 
glibc 2.33 due to its slushy freeze.
  
Adhemerval Zanella Jan. 13, 2021, 7:21 p.m. UTC | #4
On 13/01/2021 16:19, Paul Eggert wrote:
> Thanks, I'll try to take a look at these.
> 
> Also, I've been trying to pry free some time to review the patches you proposed earlier for fnmatch and glob. I'll respond on those threads with what I have now. I'm assuming that those patches won't get into glibc 2.33 due to its slushy freeze.

Thanks and my plan for these patches is for next release (2.34).
  
Adhemerval Zanella Feb. 9, 2021, 2:07 p.m. UTC | #5
On 13/01/2021 15:30, Adhemerval Zanella wrote:
> 
> 
> On 13/01/2021 15:09, Joseph Myers wrote:
>> On Wed, 13 Jan 2021, Adhemerval Zanella via Libc-alpha wrote:
>>
>>> +#if defined __STDC_VERSION__ && 201710L < __STDC_VERSION__
>>> +# define __attribute_maybe_unused__ [[__maybe_unused__]]
>>
>> I don't think that will work with GCC 9 -std=c2x or -std=gnu2x (support 
>> for [[]] attributes was added in GCC 10).  This macro isn't used at all in 
>> glibc, what compilers and options are expected to be supported for it in 
>> gnulib?
>>
>> If you compare __STDC_VERSION__ with the version for the previous 
>> standard, and intend to support compilers such as GCC 9 -std=gnu2x, you 
>> need to deal with incomplete implementations using placeholder values 
>> (202000L in this case).  (You might have incomplete implementations even 
>> comparing with the final value used for C23, but they're less likely to be 
>> so incomplete.)
>>
>> When you're supporting [[__maybe_unused__]] you might want to support it 
>> for C++17 as well as C2x.  Or is this macro in gnulib only intended to be 
>> used in C code, not C++?
>>
> 
> It is only used on C code, more specially for lib/malloc/dynarray-skeleton.c.
> And I am no sure if gnulib has active support -std=c2x or -std=gnu2x and
> I think Paul can give us a better idea on how to support this better on
> gnulib side.
> 

I won't sync the '[[__maybe_unused__]]' definition and I will check with gnulib
developers how we can safely enable it with newer gcc and -std definitions.
  

Patch

--- ../../gnulib/gnulib-lib/lib/cdefs.h 2021-01-08 17:10:32.683471041 -0300
+++ misc/sys/cdefs.h    2021-01-13 13:34:46.409398805 -0300
@@ -483,7 +483,7 @@ 

 /* The #ifndef lets Gnulib avoid including these on non-glibc
    platforms, where the includes typically do not exist.  */
-#ifndef __WORDSIZE
+#ifdef __GLIBC__
 # include <bits/wordsize.h>
 # include <bits/long-double.h>
 #endif

Where __WORDSIZE does not play well with internal cdefs.h that also
uses __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI.

Checked on x86_64-linux-gnu.
---
 misc/sys/cdefs.h | 142 ++++++++++++++++++++++++++++-------------------
 1 file changed, 84 insertions(+), 58 deletions(-)

diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 57ca262bdf..12a2f3c249 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -34,7 +34,27 @@ 
 #undef	__P
 #undef	__PMT
 
-#ifdef __GNUC__
+/* Compilers that lack __has_attribute may object to
+       #if defined __has_attribute && __has_attribute (...)
+   even though they do not need to evaluate the right-hand side of the &&.
+   Similarly for __has_builtin, etc.  */
+#ifdef __has_attribute
+# define __glibc_has_attribute(attr) __has_attribute (attr)
+#else
+# define __glibc_has_attribute(attr) 0
+#endif
+#ifdef __has_builtin
+# define __glibc_has_builtin(name) __has_builtin (name)
+#else
+# define __glibc_has_builtin(name) 0
+#endif
+#ifdef __has_extension
+# define __glibc_has_extension(ext) __has_extension (ext)
+#else
+# define __glibc_has_extension(ext) 0
+#endif
+
+#if defined __GNUC__ || defined __clang__
 
 /* All functions, except those with callbacks or those that
    synchronize memory, are leaf functions.  */
@@ -48,16 +68,17 @@ 
 
 /* GCC can always grok prototypes.  For C++ programs we add throw()
    to help it optimize the function calls.  But this only works with
-   gcc 2.8.x and egcs.  For gcc 3.2 and up we even mark C functions
+   gcc 2.8.x and egcs.  For gcc 3.4 and up we even mark C functions
    as non-throwing using a function attribute since programs can use
    the -fexceptions options for C code as well.  */
-# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
+# if !defined __cplusplus \
+     && (__GNUC_PREREQ (3, 4) || __glibc_has_attribute (__nothrow__))
 #  define __THROW	__attribute__ ((__nothrow__ __LEAF))
 #  define __THROWNL	__attribute__ ((__nothrow__))
 #  define __NTH(fct)	__attribute__ ((__nothrow__ __LEAF)) fct
 #  define __NTHNL(fct)  __attribute__ ((__nothrow__)) fct
 # else
-#  if defined __cplusplus && __GNUC_PREREQ (2,8)
+#  if defined __cplusplus && (__GNUC_PREREQ (2,8) || __clang_major >= 4)
 #   if __cplusplus >= 201103L
 #    define __THROW	noexcept (true)
 #   else
@@ -74,7 +95,7 @@ 
 #  endif
 # endif
 
-#else	/* Not GCC.  */
+#else	/* Not GCC or clang.  */
 
 # if (defined __cplusplus						\
       || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
@@ -87,16 +108,7 @@ 
 # define __THROWNL
 # define __NTH(fct)	fct
 
-#endif	/* GCC.  */
-
-/* Compilers that are not clang may object to
-       #if defined __clang__ && __has_extension(...)
-   even though they do not need to evaluate the right-hand side of the &&.  */
-#if defined __clang__ && defined __has_extension
-# define __glibc_clang_has_extension(ext) __has_extension (ext)
-#else
-# define __glibc_clang_has_extension(ext) 0
-#endif
+#endif	/* GCC || clang.  */
 
 /* These two macros are not used in glibc anymore.  They are kept here
    only because some other projects expect the macros to be defined.  */
@@ -149,11 +161,11 @@ 
    Headers that should use flexible arrays only if they're "real"
    (e.g. only if they won't affect sizeof()) should test
    #if __glibc_c99_flexarr_available.  */
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __HP_cc
 # define __flexarr	[]
 # define __glibc_c99_flexarr_available 1
-#elif __GNUC_PREREQ (2,97)
-/* GCC 2.97 supports C99 flexible array members as an extension,
+#elif __GNUC_PREREQ (2,97) || defined __clang__
+/* GCC 2.97 and clang support C99 flexible array members as an extension,
    even when in C89 mode or compiling C++ (any version).  */
 # define __flexarr	[]
 # define __glibc_c99_flexarr_available 1
@@ -179,7 +191,7 @@ 
    Example:
    int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */
 
-#if defined __GNUC__ && __GNUC__ >= 2
+#if (defined __GNUC__ && __GNUC__ >= 2) || (__clang_major__ >= 4)
 
 # define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))
 # ifdef __cplusplus
@@ -204,17 +216,17 @@ 
 */
 #endif
 
-/* GCC has various useful declarations that can be made with the
-   `__attribute__' syntax.  All of the ways we use this do fine if
-   they are omitted for compilers that don't understand it. */
-#if !defined __GNUC__ || __GNUC__ < 2
+/* GCC and clang have various useful declarations that can be made with
+   the '__attribute__' syntax.  All of the ways we use this do fine if
+   they are omitted for compilers that don't understand it.  */
+#if !(defined __GNUC__ || defined __clang__)
 # define __attribute__(xyz)	/* Ignore */
 #endif
 
 /* At some point during the gcc 2.96 development the `malloc' attribute
    for functions was introduced.  We don't want to use it unconditionally
    (although this would be possible) since it generates warnings.  */
-#if __GNUC_PREREQ (2,96)
+#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__malloc__)
 # define __attribute_malloc__ __attribute__ ((__malloc__))
 #else
 # define __attribute_malloc__ /* Ignore */
@@ -232,23 +244,31 @@ 
 /* At some point during the gcc 2.96 development the `pure' attribute
    for functions was introduced.  We don't want to use it unconditionally
    (although this would be possible) since it generates warnings.  */
-#if __GNUC_PREREQ (2,96)
+#if __GNUC_PREREQ (2,96) || __glibc_has_attribute (__pure__)
 # define __attribute_pure__ __attribute__ ((__pure__))
 #else
 # define __attribute_pure__ /* Ignore */
 #endif
 
 /* This declaration tells the compiler that the value is constant.  */
-#if __GNUC_PREREQ (2,5)
+#if __GNUC_PREREQ (2,5) || __glibc_has_attribute (__const__)
 # define __attribute_const__ __attribute__ ((__const__))
 #else
 # define __attribute_const__ /* Ignore */
 #endif
 
+#if defined __STDC_VERSION__ && 201710L < __STDC_VERSION__
+# define __attribute_maybe_unused__ [[__maybe_unused__]]
+#elif __GNUC_PREREQ (2,7) || __glibc_has_attribute (__unused__)
+# define __attribute_maybe_unused__ __attribute__ ((__unused__))
+#else
+# define __attribute_maybe_unused__ /* Ignore */
+#endif
+
 /* At some point during the gcc 3.1 development the `used' attribute
    for functions was introduced.  We don't want to use it unconditionally
    (although this would be possible) since it generates warnings.  */
-#if __GNUC_PREREQ (3,1)
+#if __GNUC_PREREQ (3,1) || __glibc_has_attribute (__used__)
 # define __attribute_used__ __attribute__ ((__used__))
 # define __attribute_noinline__ __attribute__ ((__noinline__))
 #else
@@ -257,7 +277,7 @@ 
 #endif
 
 /* Since version 3.2, gcc allows marking deprecated functions.  */
-#if __GNUC_PREREQ (3,2)
+#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__deprecated__)
 # define __attribute_deprecated__ __attribute__ ((__deprecated__))
 #else
 # define __attribute_deprecated__ /* Ignore */
@@ -267,7 +287,7 @@ 
    when a deprecated function is used.  clang claims to be gcc 4.2, but
    may also support this feature.  */
 #if __GNUC_PREREQ (4,5) \
-    || __glibc_clang_has_extension (__attribute_deprecated_with_message__)
+    || __glibc_has_extension (__attribute_deprecated_with_message__)
 # define __attribute_deprecated_msg__(msg) \
 	 __attribute__ ((__deprecated__ (msg)))
 #else
@@ -280,7 +300,7 @@ 
    If several `format_arg' attributes are given for the same function, in
    gcc-3.0 and older, all but the last one are ignored.  In newer gccs,
    all designated arguments are considered.  */
-#if __GNUC_PREREQ (2,8)
+#if __GNUC_PREREQ (2,8) || __glibc_has_attribute (__format_arg__)
 # define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
 #else
 # define __attribute_format_arg__(x) /* Ignore */
@@ -290,27 +310,30 @@ 
    attribute for functions was introduced.  We don't want to use it
    unconditionally (although this would be possible) since it
    generates warnings.  */
-#if __GNUC_PREREQ (2,97)
+#if __GNUC_PREREQ (2,97) || __glibc_has_attribute (__format__)
 # define __attribute_format_strfmon__(a,b) \
   __attribute__ ((__format__ (__strfmon__, a, b)))
 #else
 # define __attribute_format_strfmon__(a,b) /* Ignore */
 #endif
 
-/* The nonull function attribute allows to mark pointer parameters which
-   must not be NULL.  */
-#if __GNUC_PREREQ (3,3)
-# define __nonnull(params) __attribute__ ((__nonnull__ params))
-#else
-# define __nonnull(params)
+/* The nonnull function attribute marks pointer parameters that
+   must not be NULL.  Do not define __nonnull if it is already defined,
+   for portability when this file is used in Gnulib.  */
+#ifndef __nonnull
+# if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__)
+#  define __nonnull(params) __attribute__ ((__nonnull__ params))
+# else
+#  define __nonnull(params)
+# endif
 #endif
 
 /* If fortification mode, we warn about unused results of certain
    function calls which can lead to problems.  */
-#if __GNUC_PREREQ (3,4)
+#if __GNUC_PREREQ (3,4) || __glibc_has_attribute (__warn_unused_result__)
 # define __attribute_warn_unused_result__ \
    __attribute__ ((__warn_unused_result__))
-# if __USE_FORTIFY_LEVEL > 0
+# if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0
 #  define __wur __attribute_warn_unused_result__
 # endif
 #else
@@ -321,7 +344,7 @@ 
 #endif
 
 /* Forces a function to be always inlined.  */
-#if __GNUC_PREREQ (3,2)
+#if __GNUC_PREREQ (3,2) || __glibc_has_attribute (__always_inline__)
 /* The Linux kernel defines __always_inline in stddef.h (283d7573), and
    it conflicts with this definition.  Therefore undefine it first to
    allow either header to be included first.  */
@@ -334,7 +357,7 @@ 
 
 /* Associate error messages with the source location of the call site rather
    than with the source location inside the function.  */
-#if __GNUC_PREREQ (4,3)
+#if __GNUC_PREREQ (4,3) || __glibc_has_attribute (__artificial__)
 # define __attribute_artificial__ __attribute__ ((__artificial__))
 #else
 # define __attribute_artificial__ /* Ignore */
@@ -377,12 +400,14 @@ 
    run in pedantic mode if the uses are carefully marked using the
    `__extension__' keyword.  But this is not generally available before
    version 2.8.  */
-#if !__GNUC_PREREQ (2,8)
+#if !(__GNUC_PREREQ (2,8) || defined __clang__)
 # define __extension__		/* Ignore */
 #endif
 
-/* __restrict is known in EGCS 1.2 and above. */
-#if !__GNUC_PREREQ (2,92)
+/* __restrict is known in EGCS 1.2 and above, and in clang.
+   It works also in C++ mode (outside of arrays), but only when spelled
+   as '__restrict', not 'restrict'.  */
+#if !(__GNUC_PREREQ (2,92) || __clang_major__ >= 3)
 # if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
 #  define __restrict	restrict
 # else
@@ -392,8 +417,9 @@ 
 
 /* ISO C99 also allows to declare arrays as non-overlapping.  The syntax is
      array_name[restrict]
-   GCC 3.1 supports this.  */
-#if __GNUC_PREREQ (3,1) && !defined __GNUG__
+   GCC 3.1 and clang support this.
+   This syntax is not usable in C++ mode.  */
+#if (__GNUC_PREREQ (3,1) || __clang_major__ >= 3) && !defined __cplusplus
 # define __restrict_arr	__restrict
 #else
 # ifdef __GNUC__
@@ -408,7 +434,7 @@ 
 # endif
 #endif
 
-#if __GNUC__ >= 3
+#if (__GNUC__ >= 3) || __glibc_has_builtin (__builtin_expect)
 # define __glibc_unlikely(cond)	__builtin_expect ((cond), 0)
 # define __glibc_likely(cond)	__builtin_expect ((cond), 1)
 #else
@@ -416,15 +442,10 @@ 
 # define __glibc_likely(cond)	(cond)
 #endif
 
-#ifdef __has_attribute
-# define __glibc_has_attribute(attr)	__has_attribute (attr)
-#else
-# define __glibc_has_attribute(attr)	0
-#endif
-
 #if (!defined _Noreturn \
      && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
-     &&  !__GNUC_PREREQ (4,7))
+     &&  !(__GNUC_PREREQ (4,7) \
+           || (3 < __clang_major__ + (5 <= __clang_minor__))))
 # if __GNUC_PREREQ (2,8)
 #  define _Noreturn __attribute__ ((__noreturn__))
 # else
@@ -453,14 +474,19 @@ 
 
 #if (!defined _Static_assert && !defined __cplusplus \
      && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
-     && (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__))
+     && (!(__GNUC_PREREQ (4, 6) || __clang_major__ >= 4) \
+         || defined __STRICT_ANSI__))
 # define _Static_assert(expr, diagnostic) \
     extern int (*__Static_assert_function (void)) \
       [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
 #endif
 
-#include <bits/wordsize.h>
-#include <bits/long-double.h>
+/* The #ifndef lets Gnulib avoid including these on non-glibc
+   platforms, where the includes typically do not exist.  */
+#ifdef __GLIBC__
+# include <bits/wordsize.h>
+# include <bits/long-double.h>
+#endif
 
 #if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
 # ifdef __REDIRECT
@@ -550,7 +576,7 @@  _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf
    check is required to enable the use of generic selection.  */
 #if !defined __cplusplus \
     && (__GNUC_PREREQ (4, 9) \
-	|| __glibc_clang_has_extension (c_generic_selections) \
+	|| __glibc_has_extension (c_generic_selections) \
 	|| (!defined __GNUC__ && defined __STDC_VERSION__ \
 	    && __STDC_VERSION__ >= 201112L))
 # define __HAVE_GENERIC_SELECTION 1