C23 support in Autoconf

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I installed the attached patch into Savannah master to get the ball rolling on Autoconf supporting C23.

Most C23 compatibility gizmos are now done in Gnulib. However, Autoconf's AC_PROG_CC needs to be changed to tack --std=gnu23 onto $CC. Although this may cause a few backward compatibility hassles with ancient packages that still use K&R C functions, C23 means these packages need to be changed to use function prototypes anyway.

Comments welcome.
From 653956f44683e1daed9827de429590bdd2e317e7 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@xxxxxxxxxxx>
Date: Tue, 30 Apr 2024 10:26:50 -0700
Subject: [PATCH] AC_PROG_CC now tries C23 too

As C23 is now mostly supported by GCC, it's time for
AC_PROG_CC to prefer C23 if available.
* lib/autoconf/c.m4 (_AC_C_C23_TEST_GLOBALS, _AC_C_C23_TEST_MAIN):
(_AC_C_C23_TEST_PROGRAM, _AC_C_C23_OPTIONS): New macros.
(_AC_PROG_CC_STDC_EDITION): Try C23 first.
---
 NEWS              |   4 ++
 doc/autoconf.texi |  17 +++---
 lib/autoconf/c.m4 | 129 ++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 139 insertions(+), 11 deletions(-)

diff --git a/NEWS b/NEWS
index 3d968c4c..952a7cc6 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,10 @@ GNU Autoconf NEWS - User visible changes.
 
 ** Backward incompatibilities
 
+*** AC_PROG_CC now prefers C23 if available.
+  C23 has removed old-style (K&R) function definitions/declarations.
+  Old-style functions should be updated to use prototypes.
+
 *** AC_PROG_CC no longer tests for VLAs, or whether __STDC__ is defined.
   This ports better to MSVC, which does not support variable length
   arrays and does not define __STDC__.  Although C99 requires VLAs,
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 0fd82056..b50d0a2b 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -7434,14 +7434,15 @@ person building the package.  @xref{Preset Output Variables}.)
 If necessary, options are added to @code{CC} to enable support for
 ISO Standard C features with extensions, preferring the newest edition
 of the C standard for which detection is supported.  Currently the
-newest edition Autoconf knows how to detect support for is C11, as there is
-little reason to prefer C17 to C11, and C23 is still too new.  After calling
+newest edition Autoconf knows how to detect support for is C23.  After calling
 this macro you can check whether the C compiler has been set to accept
 standard C by inspecting the shell variable @code{ac_prog_cc_stdc}.
-Its value will be @samp{c11}, @samp{c99}, or @samp{c89}, respectively,
-if the C compiler has been set to use the 2011, 1999, or 1990 edition of
+Its value is @samp{c23}, @samp{c11}, @samp{c99}, or @samp{c89}, respectively,
+if the C compiler has been set to use the 2023, 2011, 1999, or 1990 edition of
 the C standard, and @samp{no} if the compiler does not support compiling
 standard C at all.
+(There is no special value for the 2017 edition of the C standard,
+as it is a minor revision that does not introduce new language features.)
 
 The tests for standard conformance are not comprehensive.  They test the
 value of @code{__STDC_VERSION__}, and a
@@ -9704,8 +9705,8 @@ checking whether we are cross compiling... no
 checking for suffix of object files... o
 checking whether the compiler supports GNU C... yes
 checking whether gcc accepts -g... yes
-checking for gcc option to enable C11 features... -std=gnu11
-checking how to run the C preprocessor... gcc -std=gnu11 -E
+checking for gcc option to enable C23 features... -std=gnu23
+checking how to run the C preprocessor... gcc -std=gnu23 -E
 OK
 @end example
 
@@ -26725,7 +26726,7 @@ checking whether we are cross compiling... no
 checking for suffix of object files... o
 checking whether the compiler supports GNU C... yes
 checking whether gcc accepts -g... yes
-checking for gcc option to enable C11 features... -std=gnu11
+checking for gcc option to enable C23 features... -std=gnu23
 checking for sys/types.h... yes
 checking for sys/stat.h... yes
 checking for strings.h... yes
@@ -26757,7 +26758,7 @@ checking whether we are cross compiling... no
 checking for suffix of object files... o
 checking whether the compiler supports GNU C... yes
 checking whether gcc accepts -g... yes
-checking for gcc option to enable C11 features... -std=gnu11
+checking for gcc option to enable C23 features... -std=gnu23
 checking for number.h... yes
 checking for pi.h... yes
 @end example
diff --git a/lib/autoconf/c.m4 b/lib/autoconf/c.m4
index d410f8bc..89f6a608 100644
--- a/lib/autoconf/c.m4
+++ b/lib/autoconf/c.m4
@@ -1103,7 +1103,7 @@ fi[]dnl
 # Warning: each test program may only use the headers required to
 # exist in the relevant standard's *freestanding* environment, in case
 # the C compiler targets such an environment.  (Therefore, almost no
-# features of the C89/C99/C11 standard *library* are probed.  Use
+# features of the C89/C99/C11/C23 standard *library* are probed.  Use
 # AC_CHECK_HEADER, AC_CHECK_FUNC, etc. for that.)  However, these
 # programs are only compiled and not linked, so it is ok to declare
 # external functions and then call them without worrying about whether
@@ -1115,6 +1115,8 @@ fi[]dnl
 #     <iso646.h> <stdbool.h> <stdint.h>
 # C11 adds:
 #     <stdalign.h> <stdnoreturn.h>
+# C23 adds:
+#     <stdbit.h>
 
 AC_DEFUN([_AC_C_C89_TEST_GLOBALS],
 [m4_divert_text([INIT_PREPARE],
@@ -1412,6 +1414,97 @@ ac_c_conftest_c11_main='
 '
 ]])])
 
+AC_DEFUN([_AC_C_C23_TEST_GLOBALS],
+[m4_divert_text([INIT_PREPARE],
+[[# Test code for whether the C compiler supports C23 (global declarations)
+ac_c_conftest_c23_globals='
+/* Does the compiler advertise conformance to C17 or earlier?
+   Although GCC 14 does not do that, even with -std=gnu23,
+   it is close enough, and defines __STDC_VERSION == 202000L.  */
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ <= 201710L
+# error "Compiler advertises conformance to C17 or earlier"
+#endif
+
+// Check alignas.
+char alignas (double) c23_aligned_as_double;
+char alignas (0) c23_no_special_alignment;
+extern char c23_aligned_as_int;
+char alignas (0) alignas (int) c23_aligned_as_int;
+
+// Check alignof.
+enum
+{
+  c23_int_alignment = alignof (int),
+  c23_int_array_alignment = alignof (int[100]),
+  c23_char_alignment = alignof (char)
+};
+static_assert (0 < -alignof (int), "alignof is signed");
+
+int function_with_unnamed_parameter (int) { return 0; }
+
+void c23_noreturn ();
+
+bool use_u8 = !u8"\xFF" == u8'\''x'\'';
+
+bool check_that_bool_works = true | false | !nullptr;
+#if !true
+# error "true does not work in #if"
+#endif
+#if false
+#elifdef __STDC_VERSION__
+#else
+# error "#elifdef does not work"
+#endif
+
+#ifndef __has_c_attribute
+# error "__has_c_attribute not defined"
+#endif
+
+#ifndef __has_include
+# error "__has_include not defined"
+#endif
+
+#define LPAREN() (
+#define FORTY_TWO(x) 42
+#define VA_OPT_TEST(r, x, ...) __VA_OPT__ (FORTY_TWO r x))
+static_assert (VA_OPT_TEST (LPAREN (), 0, <:-) == 42);
+
+static_assert (0b101010 == 42);
+static_assert (0B101010 == 42);
+static_assert (0xDEAD'\''BEEF == 3'\''735'\''928'\''559);
+static_assert (0.500'\''000'\''000 == 0.5);
+
+enum unsignedish : unsigned int { uione = 1 };
+static_assert (0 < -uione);
+
+#include <stddef.h>
+constexpr nullptr_t null_pointer = nullptr;
+
+#include <stdbit.h>
+static_assert (__STDC_ENDIAN_LITTLE__ != __STDC_ENDIAN_BIG__);
+
+static typeof (1 + 1L) two () { return 2; }
+static long int three () { return 3; }
+'
+]])])
+
+AC_DEFUN([_AC_C_C23_TEST_MAIN],
+[m4_divert_text([INIT_PREPARE],
+[[# Test code for whether the C compiler supports C23 (body of main).
+ac_c_conftest_c23_main='
+  {
+    label_before_declaration:
+      int arr[10] = {};
+      if (arr[0])
+        goto label_before_declaration;
+      if (!arr[0])
+        goto label_at_end_of_block;
+    label_at_end_of_block:
+  }
+  ok |= two != three;
+'
+]])])
+
 AC_DEFUN([_AC_C_C89_TEST_PROGRAM],
 [AC_REQUIRE([_AC_C_C89_TEST_GLOBALS])dnl
 AC_REQUIRE([_AC_C_C89_TEST_MAIN])dnl
@@ -1475,6 +1568,23 @@ main (int argc, char **argv)
 "
 ]])])
 
+AC_DEFUN([_AC_C_C23_TEST_PROGRAM],
+[AC_REQUIRE([_AC_C_C23_TEST_GLOBALS])dnl
+AC_REQUIRE([_AC_C_C23_TEST_MAIN])dnl
+m4_divert_text([INIT_PREPARE],
+[[# Test code for whether the C compiler supports C23 (complete).
+ac_c_conftest_c23_program="${ac_c_conftest_c23_globals}
+
+int
+main (int, char **)
+{
+  int ok = 0;
+  ${ac_c_conftest_c23_main}
+  return ok;
+}
+"
+]])])
+
 
 # _AC_C_C89_OPTIONS
 # -----------------
@@ -1561,13 +1671,26 @@ m4_define([_AC_C_C11_OPTIONS], [
     -std:c11
 ])
 
+# _AC_C_C23_OPTIONS
+# -----------------
+# Whitespace-separated list of options that might put the C compiler
+# into a mode conforming to ISO C 2023 with extensions.  Do not try
+# "strictly conforming" modes (e.g. gcc's -std=c23); they break some
+# systems' header files.  If more than one option is needed, put
+# shell quotes around the group.
+#
+# GCC, Clang    -std=gnu23
+m4_define([_AC_C_C23_OPTIONS], [
+    -std=gnu23
+])
+
 
 # _AC_PROG_CC_STDC_EDITION_TRY(EDITION)
 # -------------------------------------
 # Subroutine of _AC_PROG_CC_STDC_EDITION.  Not to be called directly.
 #
 # Check whether the C compiler accepts features of EDITION of the
-# C standard.  EDITION should be a two-digit year (e.g. 89, 99, 11).
+# C standard.  EDITION should be a two-digit year (e.g. 89, 99, 11, 23).
 # (FIXME: Switch to four-digit years for futureproofing.)
 # This is done by compiling the test program defined by
 # _AC_C_C{EDITION}_TEST_PROGRAM, first with no additional
@@ -1623,7 +1746,7 @@ AS_IF([test "x$ac_cv_prog_cc_c$1" = xno],
 # variable ac_prog_cc_stdc to indicate the edition.
 AC_DEFUN([_AC_PROG_CC_STDC_EDITION],
 [ac_prog_cc_stdc=no
-m4_map([_AC_PROG_CC_STDC_EDITION_TRY], [[11], [99], [89]])])
+m4_map([_AC_PROG_CC_STDC_EDITION_TRY], [[23], [11], [99], [89]])])
 
 
 # _AC_PROG_CC_C89(ACTION-IF-SUPPORTED, ACTION-IF-NOT-SUPPORTED)
-- 
2.40.1


[Index of Archives]     [GCC Help]     [Kernel Discussion]     [RPM Discussion]     [Red Hat Development]     [Yosemite News]     [Linux USB]     [Samba]

  Powered by Linux