From aa05346d645547ce6d1189d33405418f3af729c0 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Tue, 26 Nov 2024 23:53:31 +1300
Subject: [PATCH v1-9.2] If a C23 compiler is detected, try asking for C17.

Branches before 16 can't be compiled with a C23 compiler (see
deprecation warnings silenced by commit f9a56e72, and non-back-patchable
changes made in 16 by comit 1c27d16e).  Test __STDC_VERSION__, and if
it's above C17 then try appending -std=gnu17.  The test is done with the
user's CFLAGS, so an acceptable language version can also be configured
manually there.

This is done in branches 15 and older, back to 9.2, per policy of
keeping them buildable with modern tools.

Discussion: https://postgr.es/m/87o72eo9iu.fsf%40gentoo.org
---
 configure    | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++
 configure.in |  20 +++++++++
 2 files changed, 144 insertions(+)

diff --git a/configure b/configure
index ba520952fd2..fec0dd3d310 100755
--- a/configure
+++ b/configure
@@ -3975,6 +3975,130 @@ else
   fi
 fi
 
+# We use C constructs that became in invalid in C23.  Check if the compiler
+# reports a standard higher than C17, with the flags selected above (so the
+# user can control the language level explicitly to avoid the gcc/clang-only
+# fallback logic below if preferred).
+{ $as_echo "$as_me:$LINENO: checking whether $CC reports a C standard higher than ISO C17" >&5
+$as_echo_n "checking whether $CC reports a C standard higher than ISO C17... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#if __STDC_VERSION__ > 201710L
+choke me
+#endif
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  POSTC17=no
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	POSTC17=yes
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: ${POSTC17}" >&5
+$as_echo "${POSTC17}" >&6; }
+
+# If a too recent standard was detected with the user's CFLAGS, try asking for
+# C17 with GNU extensions explicitly.
+if test "$POSTC17" = yes; then
+  old_CFLAGS="$CFLAGS"
+  { $as_echo "$as_me:$LINENO: checking whether $CC supports -std=gnu17" >&5
+$as_echo_n "checking whether $CC supports -std=gnu17... " >&6; }
+if test "${pgac_cv_prog_cc_cflags__std_gnu17+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  pgac_save_CFLAGS=$CFLAGS
+CFLAGS="$pgac_save_CFLAGS -std=gnu17"
+ac_save_c_werror_flag=$ac_c_werror_flag
+ac_c_werror_flag=yes
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  pgac_cv_prog_cc_cflags__std_gnu17=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	pgac_cv_prog_cc_cflags__std_gnu17=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_c_werror_flag=$ac_save_c_werror_flag
+CFLAGS="$pgac_save_CFLAGS"
+fi
+{ $as_echo "$as_me:$LINENO: result: $pgac_cv_prog_cc_cflags__std_gnu17" >&5
+$as_echo "$pgac_cv_prog_cc_cflags__std_gnu17" >&6; }
+if test x"$pgac_cv_prog_cc_cflags__std_gnu17" = x"yes"; then
+  CFLAGS="$CFLAGS -std=gnu17"
+fi
+
+  if test "$CFLAGS" = "$old_CFLAGS"; then
+    { { $as_echo "$as_me:$LINENO: error: cannot proceed" >&5
+$as_echo "$as_me: error: cannot proceed" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
 # Some versions of GCC support some additional useful warning flags.
 # Check whether they are supported, and add them to CFLAGS if so.
 # ICC pretends to be GCC but it's lying; it doesn't support these flags,
diff --git a/configure.in b/configure.in
index 93d62944db6..b1abc3a5dc8 100644
--- a/configure.in
+++ b/configure.in
@@ -407,6 +407,26 @@ else
   fi
 fi
 
+# We use C constructs that became in invalid in C23.  Check if the compiler
+# reports a standard higher than C17, with the flags selected above (so the
+# user can control the language level explicitly to avoid the gcc/clang-only
+# fallback logic below if preferred).
+AC_MSG_CHECKING([whether $CC reports a C standard higher than ISO C17])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [@%:@if __STDC_VERSION__ > 201710L
+choke me
+@%:@endif])], [POSTC17=no], [POSTC17=yes])
+AC_MSG_RESULT(${POSTC17})
+
+# If a too recent standard was detected with the user's CFLAGS, try asking for
+# C17 with GNU extensions explicitly.
+if test "$POSTC17" = yes; then
+  old_CFLAGS="$CFLAGS"
+  PGAC_PROG_CC_CFLAGS_OPT([-std=gnu17])
+  if test "$CFLAGS" = "$old_CFLAGS"; then
+    AC_MSG_ERROR([cannot proceed])
+  fi
+fi
+
 # Some versions of GCC support some additional useful warning flags.
 # Check whether they are supported, and add them to CFLAGS if so.
 # ICC pretends to be GCC but it's lying; it doesn't support these flags,
-- 
2.47.0

