]> Savannah Git Hosting - gnulib.git/commitdiff
stddef: Define 'unreachable', for ISO C 23 compliance.
authorBruno Haible <bruno@clisp.org>
Thu, 16 Mar 2023 12:45:40 +0000 (13:45 +0100)
committerBruno Haible <bruno@clisp.org>
Thu, 16 Mar 2023 12:45:40 +0000 (13:45 +0100)
* lib/verify.h (_GL_HAS_BUILTIN_UNREACHABLE): Don't define if already
defined.
* lib/stddef.in.h (_GL_HAS_BUILTIN_UNREACHABLE, unreachable): New
macros.
(abort): Declare if needed for unreachable.
* m4/stddef_h.m4 (gl_STDDEF_H): Test for unreachable.
* tests/test-stddef.c (test_unreachable_optimization,
test_unreachable_noreturn): New functions, based on tests/test-verify.c.
* doc/posix-headers/stddef.texi: Mention unreachable.

ChangeLog
doc/posix-headers/stddef.texi
lib/stddef.in.h
lib/verify.h
m4/stddef_h.m4
tests/test-stddef.c

index b05276c8debc6e1db26e39269fd247425e7319cc..14ee3ca670241922528fc5bc4c36da77913847a9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-03-16  Bruno Haible  <bruno@clisp.org>
+
+       stddef: Define 'unreachable', for ISO C 23 compliance.
+       * lib/verify.h (_GL_HAS_BUILTIN_UNREACHABLE): Don't define if already
+       defined.
+       * lib/stddef.in.h (_GL_HAS_BUILTIN_UNREACHABLE, unreachable): New
+       macros.
+       (abort): Declare if needed for unreachable.
+       * m4/stddef_h.m4 (gl_STDDEF_H): Test for unreachable.
+       * tests/test-stddef.c (test_unreachable_optimization,
+       test_unreachable_noreturn): New functions, based on tests/test-verify.c.
+       * doc/posix-headers/stddef.texi: Mention unreachable.
+
 2023-03-10  Paul Eggert  <eggert@cs.ucla.edu>
 
        posixtm: work around Glibc time issue
index e240f93363c90e7f7770aadf5d1c9c51b479540e..33ad48244cc775c98980c1117ec4ec08f5412faf 100644 (file)
@@ -7,6 +7,10 @@ Gnulib module: stddef
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+Some platforms fail to provide @code{unreachable}, which was added in C23:
+GCC 13, clang 15, AIX with xlc 12.1, Solaris with Sun C 5.15, and others.
+
 @item
 Some platforms fail to provide @code{max_align_t}, which was added in C11:
 NetBSD 8.0, Solaris 11.0, and others.
index 6eadcc3d5a471746377f9cb76d4241fcb0c6e054..9e9d4b7cc69de219b50480d51e785e88afc2f473 100644 (file)
@@ -18,7 +18,7 @@
 /* Written by Eric Blake.  */
 
 /*
- * POSIX 2008 <stddef.h> for platforms that have issues.
+ * POSIX 2008 and ISO C 23 <stddef.h> for platforms that have issues.
  * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stddef.h.html>
  */
 
@@ -142,6 +142,43 @@ typedef union
 # endif
 #endif
 
+/* ISO C 23 ยง 7.21.1 The unreachable macro  */
+#ifndef unreachable
+
+/* Code borrowed from verify.h.  */
+# ifndef _GL_HAS_BUILTIN_UNREACHABLE
+#  if defined __clang_major__ && __clang_major__ < 5
+#   define _GL_HAS_BUILTIN_UNREACHABLE 0
+#  elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
+#   define _GL_HAS_BUILTIN_UNREACHABLE 1
+#  elif defined __has_builtin
+#   define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable)
+#  else
+#   define _GL_HAS_BUILTIN_UNREACHABLE 0
+#  endif
+# endif
+
+# if _GL_HAS_BUILTIN_UNREACHABLE
+#  define unreachable() __builtin_unreachable ()
+# elif 1200 <= _MSC_VER
+#  define unreachable() __assume (0)
+# else
+/* Declare abort(), without including <stdlib.h>.  */
+extern
+#  if defined __cplusplus
+"C"
+#  endif
+_Noreturn
+void abort (void)
+#  if defined __cplusplus && (__GLIBC__ >= 2)
+throw ()
+#  endif
+;
+#  define unreachable() abort ()
+# endif
+
+#endif
+
 #  endif /* _@GUARD_PREFIX@_STDDEF_H */
 # endif /* _@GUARD_PREFIX@_STDDEF_H */
 #endif /* __need_XXX */
index f0b3fc5851bfd4bb464e713c925364ab84f5054c..c700243209e50002269863e9a84ac50c2d5bbd0c 100644 (file)
@@ -285,14 +285,16 @@ template <int w>
 # define _GL_HAS_BUILTIN_TRAP 0
 #endif
 
-#if defined __clang_major__ && __clang_major__ < 5
-# define _GL_HAS_BUILTIN_UNREACHABLE 0
-#elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
-# define _GL_HAS_BUILTIN_UNREACHABLE 1
-#elif defined __has_builtin
-# define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable)
-#else
-# define _GL_HAS_BUILTIN_UNREACHABLE 0
+#ifndef _GL_HAS_BUILTIN_UNREACHABLE
+# if defined __clang_major__ && __clang_major__ < 5
+#  define _GL_HAS_BUILTIN_UNREACHABLE 0
+# elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
+#  define _GL_HAS_BUILTIN_UNREACHABLE 1
+# elif defined __has_builtin
+#  define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable)
+# else
+#  define _GL_HAS_BUILTIN_UNREACHABLE 0
+# endif
 #endif
 
 /* Each of these macros verifies that its argument R is nonzero.  To
index a2322ebb7ee1baa9138332201ec1173a990907cb..aa012219fcd39a322abd3874e6ae4d50e4f97822 100644 (file)
@@ -1,4 +1,4 @@
-# stddef_h.m4 serial 13
+# stddef_h.m4 serial 14
 dnl Copyright (C) 2009-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -68,6 +68,21 @@ AC_DEFUN_ONCE([gl_STDDEF_H],
     GL_GENERATE_STDDEF_H=true
   fi
 
+  AC_CACHE_CHECK([for unreachable],
+    [gl_cv_func_unreachable],
+    [AC_LINK_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <stddef.h>
+          ]],
+          [[unreachable ();
+          ]])],
+       [gl_cv_func_unreachable=yes],
+       [gl_cv_func_unreachable=no])
+    ])
+  if test $gl_cv_func_unreachable = no; then
+    GL_GENERATE_STDDEF_H=true
+  fi
+
   if $GL_GENERATE_STDDEF_H; then
     gl_NEXT_HEADERS([stddef.h])
   fi
index 1d674b3cea3a8aa295df67d351927ae43ad14300..3ec00a8f25bef81656e6979799a879680e5dee38 100644 (file)
@@ -68,6 +68,30 @@ static_assert (__alignof__ (wchar_t) <= __alignof__ (max_align_t));
 static_assert (__alignof__ (struct d) <= __alignof__ (max_align_t));
 #endif
 
+int test_unreachable_optimization (int x);
+_Noreturn void test_unreachable_noreturn (void);
+
+int
+test_unreachable_optimization (int x)
+{
+  /* Check that the compiler uses 'unreachable' for optimization.
+     This function, when compiled with optimization, should have code
+     equivalent to
+       return x + 3;
+     Use 'objdump --disassemble test-stddef.o' to verify this.  */
+  if (x < 4)
+    unreachable ();
+  return (x > 1 ? x + 3 : 2 * x + 10);
+}
+
+_Noreturn void
+test_unreachable_noreturn (void)
+{
+  /* Check that the compiler's data-flow analysis recognizes 'unreachable ()'.
+     This function should not elicit a warning.  */
+  unreachable ();
+}
+
 int
 main (void)
 {