diff options
Diffstat (limited to 'gl/verify.h')
| -rw-r--r-- | gl/verify.h | 99 |
1 files changed, 71 insertions, 28 deletions
diff --git a/gl/verify.h b/gl/verify.h index b63cb264..3b01d7c2 100644 --- a/gl/verify.h +++ b/gl/verify.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Compile-time assert-like macros. | 1 | /* Compile-time assert-like macros. |
| 2 | 2 | ||
| 3 | Copyright (C) 2005-2006, 2009-2023 Free Software Foundation, Inc. | 3 | Copyright (C) 2005-2006, 2009-2025 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| 6 | it under the terms of the GNU Lesser General Public License as | 6 | it under the terms of the GNU Lesser General Public License as |
| @@ -34,11 +34,12 @@ | |||
| 34 | #ifndef __cplusplus | 34 | #ifndef __cplusplus |
| 35 | # if (201112 <= __STDC_VERSION__ \ | 35 | # if (201112 <= __STDC_VERSION__ \ |
| 36 | || (!defined __STRICT_ANSI__ \ | 36 | || (!defined __STRICT_ANSI__ \ |
| 37 | && (4 < __GNUC__ + (6 <= __GNUC_MINOR__) || 5 <= __clang_major__))) | 37 | && ((4 < __GNUC__ + (6 <= __GNUC_MINOR__) && !defined __clang__) \ |
| 38 | || 5 <= __clang_major__))) | ||
| 38 | # define _GL_HAVE__STATIC_ASSERT 1 | 39 | # define _GL_HAVE__STATIC_ASSERT 1 |
| 39 | # endif | 40 | # endif |
| 40 | # if (202311 <= __STDC_VERSION__ \ | 41 | # if (202311 <= __STDC_VERSION__ \ |
| 41 | || (!defined __STRICT_ANSI__ && 9 <= __GNUC__)) | 42 | || (!defined __STRICT_ANSI__ && 9 <= __GNUC__ && !defined __clang__)) |
| 42 | # define _GL_HAVE__STATIC_ASSERT1 1 | 43 | # define _GL_HAVE__STATIC_ASSERT1 1 |
| 43 | # endif | 44 | # endif |
| 44 | #endif | 45 | #endif |
| @@ -156,9 +157,10 @@ | |||
| 156 | #define _GL_CONCAT0(x, y) x##y | 157 | #define _GL_CONCAT0(x, y) x##y |
| 157 | 158 | ||
| 158 | /* _GL_COUNTER is an integer, preferably one that changes each time we | 159 | /* _GL_COUNTER is an integer, preferably one that changes each time we |
| 159 | use it. Use __COUNTER__ if it works, falling back on __LINE__ | 160 | use it. Use __COUNTER__ if it works (it does so with most compilers, |
| 160 | otherwise. __LINE__ isn't perfect, but it's better than a | 161 | see <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3457.htm>), |
| 161 | constant. */ | 162 | falling back on __LINE__ otherwise. __LINE__ isn't perfect, but it's |
| 163 | better than a constant. */ | ||
| 162 | #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ | 164 | #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ |
| 163 | # define _GL_COUNTER __COUNTER__ | 165 | # define _GL_COUNTER __COUNTER__ |
| 164 | #else | 166 | #else |
| @@ -188,9 +190,9 @@ template <int w> | |||
| 188 | _gl_verify_type<(R) ? 1 : -1> | 190 | _gl_verify_type<(R) ? 1 : -1> |
| 189 | #elif defined _GL_HAVE__STATIC_ASSERT | 191 | #elif defined _GL_HAVE__STATIC_ASSERT |
| 190 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | 192 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
| 191 | struct { \ | 193 | struct { \ |
| 192 | _Static_assert (R, DIAGNOSTIC); \ | 194 | _Static_assert (R, DIAGNOSTIC); \ |
| 193 | int _gl_dummy; \ | 195 | int _gl_dummy; \ |
| 194 | } | 196 | } |
| 195 | #else | 197 | #else |
| 196 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | 198 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
| @@ -212,37 +214,74 @@ template <int w> | |||
| 212 | #elif defined _GL_HAVE__STATIC_ASSERT | 214 | #elif defined _GL_HAVE__STATIC_ASSERT |
| 213 | # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) | 215 | # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) |
| 214 | #else | 216 | #else |
| 215 | # define _GL_VERIFY(R, DIAGNOSTIC, ...) \ | 217 | # define _GL_VERIFY(R, DIAGNOSTIC, ...) \ |
| 216 | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ | 218 | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ |
| 217 | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] | 219 | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] |
| 218 | # if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) | 220 | # if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) && !defined __clang__ |
| 219 | # pragma GCC diagnostic ignored "-Wnested-externs" | 221 | # pragma GCC diagnostic ignored "-Wnested-externs" |
| 220 | # endif | 222 | # endif |
| 221 | #endif | 223 | #endif |
| 222 | 224 | ||
| 223 | /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ | 225 | /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ |
| 224 | #ifdef _GL_STATIC_ASSERT_H | 226 | #ifdef _GL_STATIC_ASSERT_H |
| 225 | # if !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert | 227 | /* Define _Static_assert if needed. */ |
| 228 | /* With clang ≥ 3.8.0 in C++ mode, _Static_assert already works and accepts | ||
| 229 | 1 or 2 arguments. We better don't override it, because clang's standard | ||
| 230 | C++ library uses static_assert inside classes in several places, and our | ||
| 231 | replacement via _GL_VERIFY does not work in these contexts. */ | ||
| 232 | # if (defined __cplusplus && defined __clang__ \ | ||
| 233 | && (4 <= __clang_major__ + (8 <= __clang_minor__))) | ||
| 234 | # if 5 <= __clang_major__ | ||
| 235 | /* Avoid "warning: 'static_assert' with no message is a C++17 extension". */ | ||
| 236 | # pragma clang diagnostic ignored "-Wc++17-extensions" | ||
| 237 | # else | ||
| 238 | /* Avoid "warning: static_assert with no message is a C++1z extension". */ | ||
| 239 | # pragma clang diagnostic ignored "-Wc++1z-extensions" | ||
| 240 | # endif | ||
| 241 | # elif !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert | ||
| 226 | # if !defined _MSC_VER || defined __clang__ | 242 | # if !defined _MSC_VER || defined __clang__ |
| 227 | # define _Static_assert(...) \ | 243 | # define _Static_assert(...) \ |
| 228 | _GL_VERIFY (__VA_ARGS__, "static assertion failed", -) | 244 | _GL_VERIFY (__VA_ARGS__, "static assertion failed", -) |
| 229 | # else | 245 | # else |
| 230 | /* Work around MSVC preprocessor incompatibility with ISO C; see | 246 | # if defined __cplusplus && _MSC_VER >= 1910 |
| 231 | <https://stackoverflow.com/questions/5134523/>. */ | 247 | /* In MSVC 14.1 or newer, static_assert accepts one or two arguments, |
| 232 | # define _Static_assert(R, ...) \ | 248 | but _Static_assert is not defined. */ |
| 233 | _GL_VERIFY ((R), "static assertion failed", -) | 249 | # define _Static_assert static_assert |
| 250 | # else | ||
| 251 | /* Work around MSVC preprocessor incompatibility with ISO C; see | ||
| 252 | <https://stackoverflow.com/questions/5134523/>. */ | ||
| 253 | # define _Static_assert(R, ...) \ | ||
| 254 | _GL_VERIFY ((R), "static assertion failed", -) | ||
| 255 | # endif | ||
| 234 | # endif | 256 | # endif |
| 235 | # endif | 257 | # endif |
| 258 | /* Define static_assert if needed. */ | ||
| 259 | # if defined __cplusplus && defined __clang__ && __clang_major__ < 9 | ||
| 260 | /* clang++ before commit 5c739665a8721228cf6143fd4ef95870a59f55ae had a | ||
| 261 | two-arguments static_assert but not the one-argument static_assert. */ | ||
| 262 | # undef static_assert | ||
| 263 | # endif | ||
| 236 | # if (!defined static_assert \ | 264 | # if (!defined static_assert \ |
| 237 | && __STDC_VERSION__ < 202311 \ | 265 | && __STDC_VERSION__ < 202311 \ |
| 238 | && (!defined __cplusplus \ | 266 | && (!defined __cplusplus \ |
| 239 | || (__cpp_static_assert < 201411 \ | 267 | || (__cpp_static_assert < 201411 \ |
| 240 | && __GNUG__ < 6 && __clang_major__ < 6))) | 268 | && __GNUG__ < 6 && __clang_major__ < 6 && _MSC_VER < 1910))) |
| 241 | # if defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__ | 269 | # if (defined __cplusplus && defined __GNUG__ && __GNUG__ < 6 \ |
| 270 | && __cplusplus == 201103L && !defined __clang__) | ||
| 271 | /* g++ >= 4.7, < 6 with option -std=c++11 or -std=gnu++11 supports the | ||
| 272 | two-arguments static_assert but not the one-argument static_assert, and | ||
| 273 | it does not support _Static_assert. | ||
| 274 | We have to play preprocessor tricks to distinguish the two cases. */ | ||
| 275 | # define _GL_SA1(a1) static_assert ((a1), "static assertion failed") | ||
| 276 | # define _GL_SA2 static_assert | ||
| 277 | # define _GL_SA3 static_assert | ||
| 278 | # define _GL_SA_PICK(x1,x2,x3,x4,...) x4 | ||
| 279 | # define static_assert(...) _GL_SA_PICK(__VA_ARGS__,_GL_SA3,_GL_SA2,_GL_SA1) (__VA_ARGS__) | ||
| 280 | # elif defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__ | ||
| 242 | /* MSVC 14 in C++ mode supports the two-arguments static_assert but not | 281 | /* MSVC 14 in C++ mode supports the two-arguments static_assert but not |
| 243 | the one-argument static_assert, and it does not support _Static_assert. | 282 | the one-argument static_assert, and it does not support _Static_assert. |
| 244 | We have to play preprocessor tricks to distinguish the two cases. | 283 | We have to play preprocessor tricks to distinguish the two cases. |
| 245 | Since the MSVC preprocessor is not ISO C compliant (see above),. | 284 | Since the MSVC preprocessor is not ISO C compliant (see above), |
| 246 | the solution is specific to MSVC. */ | 285 | the solution is specific to MSVC. */ |
| 247 | # define _GL_EXPAND(x) x | 286 | # define _GL_EXPAND(x) x |
| 248 | # define _GL_SA1(a1) static_assert ((a1), "static assertion failed") | 287 | # define _GL_SA1(a1) static_assert ((a1), "static assertion failed") |
| @@ -250,6 +289,8 @@ template <int w> | |||
| 250 | # define _GL_SA3 static_assert | 289 | # define _GL_SA3 static_assert |
| 251 | # define _GL_SA_PICK(x1,x2,x3,x4,...) x4 | 290 | # define _GL_SA_PICK(x1,x2,x3,x4,...) x4 |
| 252 | # define static_assert(...) _GL_EXPAND(_GL_SA_PICK(__VA_ARGS__,_GL_SA3,_GL_SA2,_GL_SA1)) (__VA_ARGS__) | 291 | # define static_assert(...) _GL_EXPAND(_GL_SA_PICK(__VA_ARGS__,_GL_SA3,_GL_SA2,_GL_SA1)) (__VA_ARGS__) |
| 292 | /* Avoid "fatal error C1189: #error: The C++ Standard Library forbids macroizing keywords." */ | ||
| 293 | # define _ALLOW_KEYWORD_MACROS 1 | ||
| 253 | # else | 294 | # else |
| 254 | # define static_assert _Static_assert /* C11 requires this #define. */ | 295 | # define static_assert _Static_assert /* C11 requires this #define. */ |
| 255 | # endif | 296 | # endif |
| @@ -268,14 +309,16 @@ template <int w> | |||
| 268 | # define _GL_HAS_BUILTIN_TRAP 0 | 309 | # define _GL_HAS_BUILTIN_TRAP 0 |
| 269 | #endif | 310 | #endif |
| 270 | 311 | ||
| 271 | #if defined __clang_major__ && __clang_major__ < 5 | 312 | #ifndef _GL_HAS_BUILTIN_UNREACHABLE |
| 272 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | 313 | # if defined __clang_major__ && __clang_major__ < 5 |
| 273 | #elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) | 314 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 |
| 274 | # define _GL_HAS_BUILTIN_UNREACHABLE 1 | 315 | # elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) && !defined __clang__ |
| 275 | #elif defined __has_builtin | 316 | # define _GL_HAS_BUILTIN_UNREACHABLE 1 |
| 276 | # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) | 317 | # elif defined __has_builtin |
| 277 | #else | 318 | # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) |
| 278 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | 319 | # else |
| 320 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | ||
| 321 | # endif | ||
| 279 | #endif | 322 | #endif |
| 280 | 323 | ||
| 281 | /* Each of these macros verifies that its argument R is nonzero. To | 324 | /* Each of these macros verifies that its argument R is nonzero. To |
