+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
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.
/* 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>
*/
# 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 */
# 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
-# 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,
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
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)
{