diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2023-09-08 18:19:26 +0300 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2023-09-22 20:06:21 +0300 |
commit | 90c94dddfd57b7d744bfad64c54e10d15778144b (patch) | |
tree | 4319b205d0cdeed9abbc38b3b9555c56845ac158 /src/common | |
parent | Update THANKS. (diff) | |
download | xz-90c94dddfd57b7d744bfad64c54e10d15778144b.tar.xz |
tuklib: Update tuklib_attr_noreturn for C11/C17 and C23.
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.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/tuklib_common.h | 22 | ||||
-rw-r--r-- | src/common/tuklib_exit.h | 4 |
2 files changed, 23 insertions, 3 deletions
diff --git a/src/common/tuklib_common.h b/src/common/tuklib_common.h index b1f531ea..724b8c0e 100644 --- a/src/common/tuklib_common.h +++ b/src/common/tuklib_common.h @@ -57,8 +57,28 @@ # 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 diff --git a/src/common/tuklib_exit.h b/src/common/tuklib_exit.h index b11776f0..f8f35a6b 100644 --- a/src/common/tuklib_exit.h +++ b/src/common/tuklib_exit.h @@ -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 |