Bruno Haible wrote:
IMO the only way to reliably use <libc-config.h> would be that after
including it, you don't include any system headers any more.

Thanks for checking the port to FreeBSD 11. It appears that the problem is planned to go away in FreeBSD 12 (they've removed the cdefs.h __inline #define in their development version), so I hope this sort of thing is a one-off.

I guess you're suggesting two include files? config.h has to come first, so there'd be another include file (let's say, configlast.h) that would come last. I think something like that would work, though it would complicate the shared-with-glibc files a bit more, and even then it wouldn't be 100% reliable because system include files could define macros that are expanded after configlast.h is included.

If this is the only such problem we run into I'm not sure it's worth the hassle of having multiple includes. If we run into more such problems, we can keep this idea in reserve, though.

In the meantime this change got me to looking, and glibc has updated cdefs.h: it's fixed one portability bug that can let us simplify libc-config.h, has partially fixed another (not good enough, if you ask me), and added another macro. I would like to keep Gnulib cdefs.h in sync with glibc as much as possible, and installed the attached.
From d9443441ff5ceb940d62878d5e1c0dd1d1e8ac62 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sun, 24 Jun 2018 08:50:36 -0700
Subject: [PATCH] libc-config: merge from glibc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lib/cdefs.h (__inline, __restrict):
Copy from current glibc.  This fixes glibc bug 17721,
which Gnulib had already fixed in a different way.
(__nonnull): Lessen the distance from glibc by using the
glibc definition inside an ‘#ifndef __nonnull’.
(__attribute_nonstring__): New macro, copied from
current glibc.
* lib/libc-config.h (__attribute_nonstring__): New undef.
(__restrict): Remove; workaround no longer needed.
Keep the __inline workaround, though, as it uses HAVE___INLINE to
support more compilers than the glibc __inline can.
---
 ChangeLog         | 15 +++++++++++++++
 lib/cdefs.h       | 36 ++++++++++++++++++++++++++++++------
 lib/libc-config.h | 15 +++------------
 3 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 125c66b..bb2fabf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2018-06-24  Paul Eggert  <egg...@cs.ucla.edu>
+
+       libc-config: merge from glibc
+       * lib/cdefs.h (__inline, __restrict):
+       Copy from current glibc.  This fixes glibc bug 17721,
+       which Gnulib had already fixed in a different way.
+       (__nonnull): Lessen the distance from glibc by using the
+       glibc definition inside an ‘#ifndef __nonnull’.
+       (__attribute_nonstring__): New macro, copied from
+       current glibc.
+       * lib/libc-config.h (__attribute_nonstring__): New undef.
+       (__restrict): Remove; workaround no longer needed.
+       Keep the __inline workaround, though, as it uses HAVE___INLINE to
+       support more compilers than the glibc __inline can.
+
 2018-06-24  Bruno Haible  <br...@clisp.org>
 
        mbrtowc, wcwidth: Fix MT-safety bug (regression from 2018-06-23).
diff --git a/lib/cdefs.h b/lib/cdefs.h
index 76325c5..b164531 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -72,7 +72,12 @@
 
 #else  /* Not GCC.  */
 
-# define __inline              /* No inline functions.  */
+# if (defined __cplusplus                                              \
+      || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
+#  define __inline     inline
+# else
+#  define __inline             /* No inline functions.  */
+# endif
 
 # define __THROW
 # define __THROWNL
@@ -282,10 +287,16 @@
 # define __attribute_format_strfmon__(a,b) /* Ignore */
 #endif
 
-/* The nonnull function attribute allows to mark pointer parameters which
-   must not be NULL.
-   In Gnulib we use the macro _GL_ARG_NONNULL instead of __nonnull, because
-   __nonnull is defined in an incompatible way in FreeBSD's include files.  */
+/* 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)
+#  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.  */
@@ -365,7 +376,11 @@
 
 /* __restrict is known in EGCS 1.2 and above. */
 #if !__GNUC_PREREQ (2,92)
-# define __restrict    /* Ignore */
+# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#  define __restrict   restrict
+# else
+#  define __restrict   /* Ignore */
+# endif
 #endif
 
 /* ISO C99 also allows to declare arrays as non-overlapping.  The syntax is
@@ -404,6 +419,15 @@
 # endif
 #endif
 
+#if __GNUC_PREREQ (8, 0)
+/* Describes a char array whose address can safely be passed as the first
+   argument to strncpy and strncat, as the char array is not necessarily
+   a NUL-terminated string.  */
+# define __attribute_nonstring__ __attribute__ ((__nonstring__))
+#else
+# define __attribute_nonstring__
+#endif
+
 #if (!defined _Static_assert && !defined __cplusplus \
      && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
      && (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__))
diff --git a/lib/libc-config.h b/lib/libc-config.h
index 14f0bb4..98dc7c5 100644
--- a/lib/libc-config.h
+++ b/lib/libc-config.h
@@ -33,7 +33,8 @@
 #include <config.h>
 
 /* On glibc this includes <features.h> and <sys/cdefs.h> and #defines
-   _FEATURES_H, __WORDSIZE, and __set_errno.  On other platforms this
+   _FEATURES_H, __WORDSIZE, and __set_errno.  On FreeBSD 11 it
+   includes <sys/cdefs.h> which defines __nonnull.  Elsewhere it
    is harmless.  */
 #include <errno.h>
 
@@ -118,6 +119,7 @@
 #undef __attribute_format_strfmon__
 #undef __attribute_malloc__
 #undef __attribute_noinline__
+#undef __attribute_nonstring__
 #undef __attribute_pure__
 #undef __attribute_used__
 #undef __attribute_warn_unused_result__
@@ -157,17 +159,6 @@
 # endif
 #endif
 
-/* <cdefs.h> __restrict is too pessimistic for non-GCC.  GCC 2.95 and
-   later have "__restrict", and C99 compilers have "restrict".  */
-#undef __restrict
-#if !__GNUC_PREREQ (2, 95)
-# if 199901L <= __STDC_VERSION__
-#  define __restrict restrict
-# else
-#  define __restrict
-# endif
-#endif
-
 
 /* A substitute for glibc <libc-symbols.h>, good enough for Gnulib.  */
 #define attribute_hidden
-- 
2.7.4

Reply via email to