summaryrefslogtreecommitdiffstats
path: root/gl/verify.h
diff options
context:
space:
mode:
Diffstat (limited to 'gl/verify.h')
-rw-r--r--gl/verify.h99
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