Re: [PATCH 1/2] stddef: work around GCC 14 stddef.h bugs

2024-05-01 Thread Bruno Haible
I wrote:
> I would have preferred if you had committed each workaround in a separate
> patch, because
>   - One of the two workarounds causes the major trouble on Cygwin,
> reported by Markus Mützel, therefore I have to revert it.
>   - Also the fact that the documentation mentions one of the two workarounds
> but not the other adds to the confusion.

- Also, for maintaining the stable branches. If two workarounds are in a
  single commit and I want to backport only one of them, I need to take half
  of a commit, which is quite error-prone.

Bruno






Re: [PATCH 1/2] stddef: work around GCC 14 stddef.h bugs

2024-05-01 Thread Paul Eggert

On 2024-05-01 15:32, Bruno Haible wrote:

I tried another workaround, consisting of adding
   #undef __STDC_VERSION_STDDEF_H__
at the appropriate place, but then the Fedora 40 gcc gives a warning
about this #undef. Since neither the warning about the redefinition
nor the warning about the #undef can be silenced via
   #pragma GCC diagnostic ignored "-W..."
this approach did not work.


Yes, that was the workaround I tried first, and I rejected it for the 
same reason you did.


What a mess, huh?



Re: [PATCH 1/2] stddef: work around GCC 14 stddef.h bugs

2024-05-01 Thread Bruno Haible
Hi Paul,

> * 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.

I had to revert this, since it broke Cygwin.

The workaround should be as platform specific as possible, since
fiddling with the __need_wchar_t etc. invocation convention is
risky: it is used by several platforms: older Mac OS X, Haiku, Cygwin,
and glibc.

Fortunately you already wrote the configure test for it. I only need
to pull it in.

I tried another workaround, consisting of adding
  #undef __STDC_VERSION_STDDEF_H__
at the appropriate place, but then the Fedora 40 gcc gives a warning
about this #undef. Since neither the warning about the redefinition
nor the warning about the #undef can be silenced via
  #pragma GCC diagnostic ignored "-W..."
this approach did not work.


2024-05-01  Bruno Haible  

stddef: A better workaround against GCC bug 114870.
* lib/stddef.in.h: If STDDEF_NOT_IDEMPOTENT is 1, disable the special
invocation convention.
* m4/stddef_h.m4 (gl_STDDEF_H): Set STDDEF_NOT_IDEMPOTENT.
(gl_STDDEF_H_DEFAULTS): Initialize STDDEF_NOT_IDEMPOTENT.
* modules/stddef (Makefile.am): Substitute STDDEF_NOT_IDEMPOTENT.

diff --git a/lib/stddef.in.h b/lib/stddef.in.h
index ac81257b5c..63bb500e26 100644
--- a/lib/stddef.in.h
+++ b/lib/stddef.in.h
@@ -27,9 +27,13 @@
 #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 __need_wchar_t || defined __need_size_t\
+ || defined __need_ptrdiff_t || defined __need_NULL \
+ || defined __need_wint_t)  \
+/* Avoid warning triggered by "gcc -std=gnu23 -Wsystem-headers" \
+   in Fedora 40 with gcc 14.0.1.\
+   .  */   \
+&& !@STDDEF_NOT_IDEMPOTENT@
 /* Special invocation convention inside gcc header files.  In
particular,  in some ancient versions of GCC blindly
redefined NULL when __need_wint_t was defined, even though wint_t
@@ -56,6 +60,13 @@
 # endif
 
 #else
+/* For @STDDEF_NOT_IDEMPOTENT@.  */
+# undef __need_wchar_t
+# undef __need_size_t
+# undef __need_ptrdiff_t
+# undef __need_NULL
+# undef __need_wint_t
+
 /* Normal invocation convention.  */
 
 # ifndef _@GUARD_PREFIX@_STDDEF_H
diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4
index 0d4ddf8fcb..998fe12fa8 100644
--- a/m4/stddef_h.m4
+++ b/m4/stddef_h.m4
@@ -1,5 +1,5 @@
 # stddef_h.m4
-# serial 15
+# serial 16
 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,
@@ -110,6 +110,7 @@ AC_DEFUN_ONCE([gl_STDDEF_H]
 [gl_cv_clean_version_stddef=yes],
 [gl_cv_clean_version_stddef=no])])
   if test "$gl_cv_clean_version_stddef" = no; then
+STDDEF_NOT_IDEMPOTENT=1
 GL_GENERATE_STDDEF_H=true
   fi
 
@@ -144,6 +145,7 @@ 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])
+  STDDEF_NOT_IDEMPOTENT=0;   AC_SUBST([STDDEF_NOT_IDEMPOTENT])
   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 4096ab955d..9a80db007b 100644
--- a/modules/stddef
+++ b/modules/stddef
@@ -31,10 +31,11 @@ stddef.h: stddef.in.h $(top_builddir)/config.status
  -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
  -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
  -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|@''STDDEF_NOT_IDEMPOTENT''@|$(STDDEF_NOT_IDEMPOTENT)|g' \
  -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
+ -e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \
+ -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
  $(srcdir)/stddef.in.h > $@-t
$(AM_V_at)mv $@-t $@
 else






Re: [PATCH 1/2] stddef: work around GCC 14 stddef.h bugs

2024-05-01 Thread Bruno Haible
Hi Paul,

> +2024-04-27  Paul Eggert  
> +
> + 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.

I would have preferred if you had committed each workaround in a separate
patch, because
  - One of the two workarounds causes the major trouble on Cygwin,
reported by Markus Mützel, therefore I have to revert it.
  - Also the fact that the documentation mentions one of the two workarounds
but not the other adds to the confusion.

Let me start by adding a reference from the doc to the GCC bug tracker.


diff --git a/ChangeLog b/ChangeLog
index 118eeaa050..8681066eee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2024-05-01  Bruno Haible  
+
+   doc: Reference a gcc bug.
+   * doc/posix-headers/stddef.texi: Reference a gcc bug.
+
 2024-05-01  Bruno Haible  
 
sprintf-posix, snprintf-posix tests: Add comment.
@@ -169,6 +174,7 @@
* m4/stddef_h.m4 (gl_STDDEF_H, gl_STDDEF_H_DEFAULTS):
* modules/stddef (stddef.h):
Detect the two bugs.
+   * doc/posix-headers/stddef.texi: Mention one of the two bugs.
 
 2024-04-27  Bruno Haible  
 
diff --git a/doc/posix-headers/stddef.texi b/doc/posix-headers/stddef.texi
index 00860bade0..4d0e171b8d 100644
--- a/doc/posix-headers/stddef.texi
+++ b/doc/posix-headers/stddef.texi
@@ -48,6 +48,7 @@
 @item
 Some platforms define @code{nullptr_t} even when @code{} is
 not included:
+@c https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114869
 GCC 14.0.1 20240411 (Red Hat 14.0.1-0).
 
 @item






[PATCH 1/2] stddef: work around GCC 14 stddef.h bugs

2024-04-27 Thread Paul Eggert
* 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  
+
+   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  
 
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{} 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  that blindly
-   redefines NULL even when __need_wint_t was defined, even though
-   wint_t is not normally provided by .  Hence, we must
+   particular,  in some ancient versions of GCC blindly
+   redefined NULL when __need_wint_t was defined, even though wint_t
+   is not normally provided by .
+   (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
+   .  */
+#   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 ],
+[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 
+#undef __STDC_VERSION_STDDEF_H__
+#include 
+#ifdef __STDC_VERSION_STDDEF_H__
+# error " 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_