]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
tuklib: Update tuklib_attr_noreturn for C11/C17 and C23.
authorLasse Collin <lasse.collin@tukaani.org>
Fri, 8 Sep 2023 15:19:26 +0000 (18:19 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Fri, 22 Sep 2023 17:06:21 +0000 (20:06 +0300)
This makes no difference for GCC or Clang as they support
GNU C's __attribute__((__noreturn__)) but this helps with MSVC:

  - VS 2019 version 16.7 and later support _Noreturn if the
    options /std:c11 or /std:c17 are used. This gets handled
    with the check for __STDC_VERSION__ >= 201112.

  - When MSVC isn't in C11/C17 mode, __declspec(noreturn) is used.

C23 will deprecate _Noreturn (and <stdnoreturn.h>)
for [[noreturn]]. This commit anticipates that but
the final __STDC_VERSION__ value isn't known yet.

src/common/tuklib_common.h
src/common/tuklib_exit.h

index b1f531ea4a68cdd2d7a250ae5603ee1f4ed88641..724b8c0e791f46e2c32492264822e8a2eecae417 100644 (file)
 #      define TUKLIB_GNUC_REQ(major, minor) 0
 #endif
 
-#if TUKLIB_GNUC_REQ(2, 5)
+// tuklib_attr_noreturn attribute is used to mark functions as non-returning.
+// We cannot use "noreturn" as the macro name because then C23 code that
+// uses [[noreturn]] would break as it would expand to [[ [[noreturn]] ]].
+//
+// tuklib_attr_noreturn must be used at the beginning of function declaration
+// to work in all cases. The [[noreturn]] syntax is the most limiting, it
+// must be even before any GNU C's __attribute__ keywords:
+//
+//     tuklib_attr_noreturn
+//     __attribute__((nonnull(1)))
+//     extern void foo(const char *s);
+//
+// FIXME: Update __STDC_VERSION__ for the final C23 version. 202000 is used
+// by GCC 13 and Clang 15 with -std=c2x.
+#if   defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000
+#      define tuklib_attr_noreturn [[noreturn]]
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112
+#      define tuklib_attr_noreturn _Noreturn
+#elif TUKLIB_GNUC_REQ(2, 5)
 #      define tuklib_attr_noreturn __attribute__((__noreturn__))
+#elif defined(_MSC_VER)
+#      define tuklib_attr_noreturn __declspec(noreturn)
 #else
 #      define tuklib_attr_noreturn
 #endif
index b11776f0e5bfece01e178450a1e7af4796831fe8..f8f35a6b14245a4a6a2c446d0e11f1a287d4982d 100644 (file)
@@ -18,8 +18,8 @@
 TUKLIB_DECLS_BEGIN
 
 #define tuklib_exit TUKLIB_SYMBOL(tuklib_exit)
-extern void tuklib_exit(int status, int err_status, int show_error)
-               tuklib_attr_noreturn;
+tuklib_attr_noreturn
+extern void tuklib_exit(int status, int err_status, int show_error);
 
 TUKLIB_DECLS_END
 #endif