* lib/stddef.in.h: Do nothing if _@GUARD_PREFIX@_STDDEF_H is
defined, as stddef.h has already been included.  This works
around GCC bug 114870.
(_GCC_NULLPTR_T): Define if needed to work around GCC bug 114869.
* m4/stddef_h.m4 (gl_STDDEF_H, gl_STDDEF_H_DEFAULTS):
* modules/stddef (stddef.h):
Detect the two bugs.
---
 ChangeLog                     | 11 +++++++++++
 doc/posix-headers/stddef.texi |  5 +++++
 lib/stddef.in.h               | 23 +++++++++++++++++------
 m4/stddef_h.m4                | 32 +++++++++++++++++++++++++++++++-
 modules/stddef                |  1 +
 5 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dacf6892b1..b30238f934 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2024-04-27  Paul Eggert  <egg...@cs.ucla.edu>
+
+       stddef: work around GCC 14 stddef.h bugs
+       * lib/stddef.in.h: Do nothing if _@GUARD_PREFIX@_STDDEF_H is
+       defined, as stddef.h has already been included.  This works
+       around GCC bug 114870.
+       (_GCC_NULLPTR_T): Define if needed to work around GCC bug 114869.
+       * m4/stddef_h.m4 (gl_STDDEF_H, gl_STDDEF_H_DEFAULTS):
+       * modules/stddef (stddef.h):
+       Detect the two bugs.
+
 2024-04-27  Bruno Haible  <br...@clisp.org>
 
        bootstrap: Support checking out a recent GNULIB_REVISION.
diff --git a/doc/posix-headers/stddef.texi b/doc/posix-headers/stddef.texi
index 33ad48244c..0e331481aa 100644
--- a/doc/posix-headers/stddef.texi
+++ b/doc/posix-headers/stddef.texi
@@ -45,6 +45,11 @@ Some platforms fail to provide @code{nullptr_t},
 which Gnulib cannot usefully emulate:
 GCC 12, Clang 15, and other pre-2023 C compilers.
 
+@item
+Some platforms define @code{nullptr_t} even when @code{<stddef.h>} is
+not included:
+GCC 14.0.
+
 @item
 Some platforms provide an @code{offsetof} macro that cannot be used in
 arbitrary expressions:
diff --git a/lib/stddef.in.h b/lib/stddef.in.h
index fa8998d9b7..fa249259cd 100644
--- a/lib/stddef.in.h
+++ b/lib/stddef.in.h
@@ -27,13 +27,18 @@
 #endif
 @PRAGMA_COLUMNS@
 
-#if defined __need_wchar_t || defined __need_size_t  \
-  || defined __need_ptrdiff_t || defined __need_NULL \
-  || defined __need_wint_t
+#if (!defined _@GUARD_PREFIX@_STDDEF_H \
+     && (defined __need_wchar_t || defined __need_size_t \
+         || defined __need_ptrdiff_t || defined __need_NULL \
+         || defined __need_wint_t))
 /* Special invocation convention inside gcc header files.  In
-   particular, gcc provides a version of <stddef.h> that blindly
-   redefines NULL even when __need_wint_t was defined, even though
-   wint_t is not normally provided by <stddef.h>.  Hence, we must
+   particular, <stddef.h> in some ancient versions of GCC blindly
+   redefined NULL when __need_wint_t was defined, even though wint_t
+   is not normally provided by <stddef.h>.
+   (FIXME: It's not clear what GCC versions those were - perhaps so
+   ancient that we can stop worrying about this?)
+   Although glibc 2.26 (2017) and later do not use __need_wint_t,
+   for portability to older Glibc + GCC,
    remember if special invocation has ever been used to obtain wint_t,
    in which case we need to clean up NULL yet again.  */
 
@@ -74,6 +79,12 @@ typedef long max_align_t;
 #   endif
 #  endif
 
+#  if !defined _GCC_NULLPTR_T && !@NULLPTR_T_NEEDS_STDDEF@
+    /* Suppress unwanted nullptr_t typedef.  See
+       <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114869>.  */
+#   define _GCC_NULLPTR_T
+#  endif
+
 /* The include_next requires a split double-inclusion guard.  */
 
 #  @INCLUDE_NEXT@ @NEXT_STDDEF_H@
diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4
index 84d3bae801..0d4ddf8fcb 100644
--- a/m4/stddef_h.m4
+++ b/m4/stddef_h.m4
@@ -1,5 +1,5 @@
 # stddef_h.m4
-# serial 14
+# serial 15
 dnl Copyright (C) 2009-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -84,6 +84,35 @@ AC_DEFUN_ONCE([gl_STDDEF_H],
     GL_GENERATE_STDDEF_H=true
   fi
 
+  dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114869
+  AC_CACHE_CHECK([whether nullptr_t needs <stddef.h>],
+    [gl_cv_nullptr_t_needs_stddef],
+    [AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[nullptr_t x;]],
+       [gl_cv_nullptr_t_needs_stddef=no],
+       [gl_cv_nullptr_t_needs_stddef=yes])])
+  if test "$gl_cv_nullptr_t_needs_stddef" = no; then
+    NULLPTR_T_NEEDS_STDDEF=0
+    GL_GENERATE_STDDEF_H=true
+  fi
+
+  AC_CACHE_CHECK([for clean definition of __STDC_VERSION_STDDEF_H__],
+    [gl_cv_clean_version_stddef],
+    [AC_PREPROC_IFELSE(
+       [AC_LANG_SOURCE(
+          [[/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114870 */
+            #include <stddef.h>
+            #undef __STDC_VERSION_STDDEF_H__
+            #include <time.h>
+            #ifdef __STDC_VERSION_STDDEF_H__
+            # error "<time.h> defines __STDC_VERSION_STDDEF_H__"
+            #endif
+          ]])],
+        [gl_cv_clean_version_stddef=yes],
+        [gl_cv_clean_version_stddef=no])])
+  if test "$gl_cv_clean_version_stddef" = no; then
+    GL_GENERATE_STDDEF_H=true
+  fi
+
   if $GL_GENERATE_STDDEF_H; then
     gl_NEXT_HEADERS([stddef.h])
   fi
@@ -114,6 +143,7 @@ AC_DEFUN([gl_STDDEF_H_REQUIRE_DEFAULTS],
 AC_DEFUN([gl_STDDEF_H_DEFAULTS],
 [
   dnl Assume proper GNU behavior unless another module says otherwise.
+  NULLPTR_T_NEEDS_STDDEF=1;      AC_SUBST([NULLPTR_T_NEEDS_STDDEF])
   REPLACE_NULL=0;                AC_SUBST([REPLACE_NULL])
   HAVE_MAX_ALIGN_T=1;            AC_SUBST([HAVE_MAX_ALIGN_T])
   HAVE_WCHAR_T=1;                AC_SUBST([HAVE_WCHAR_T])
diff --git a/modules/stddef b/modules/stddef
index fb7214138e..4096ab955d 100644
--- a/modules/stddef
+++ b/modules/stddef
@@ -33,6 +33,7 @@ stddef.h: stddef.in.h $(top_builddir)/config.status
              -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \
              -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \
              -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
+             -e 's|@''NULLPTR_T_NEEDS_STDDEF''@|$(NULLPTR_T_NEEDS_STDDEF)|g' \
              -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
              $(srcdir)/stddef.in.h > $@-t
        $(AM_V_at)mv $@-t $@
-- 
2.44.0


Reply via email to