* 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