diff options
Diffstat (limited to 'gl/verify.h')
-rw-r--r-- | gl/verify.h | 160 |
1 files changed, 113 insertions, 47 deletions
diff --git a/gl/verify.h b/gl/verify.h index d42d0750..47b6ee66 100644 --- a/gl/verify.h +++ b/gl/verify.h | |||
@@ -1,19 +1,19 @@ | |||
1 | /* Compile-time assert-like macros. | 1 | /* Compile-time assert-like macros. |
2 | 2 | ||
3 | Copyright (C) 2005-2006, 2009-2013 Free Software Foundation, Inc. | 3 | Copyright (C) 2005-2006, 2009-2022 Free Software Foundation, Inc. |
4 | 4 | ||
5 | This program 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 General Public License as published by | 6 | it under the terms of the GNU Lesser General Public License as |
7 | the Free Software Foundation; either version 3 of the License, or | 7 | published by the Free Software Foundation; either version 2.1 of the |
8 | (at your option) any later version. | 8 | License, or (at your option) any later version. |
9 | 9 | ||
10 | This program is distributed in the hope that it will be useful, | 10 | This file is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 13 | GNU Lesser General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU Lesser General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 16 | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
17 | 17 | ||
18 | /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ | 18 | /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ |
19 | 19 | ||
@@ -21,31 +21,32 @@ | |||
21 | #define _GL_VERIFY_H | 21 | #define _GL_VERIFY_H |
22 | 22 | ||
23 | 23 | ||
24 | /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11. | 24 | /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC) |
25 | This is supported by GCC 4.6.0 and later, in C mode, and its use | 25 | works as per C11. This is supported by GCC 4.6.0+ and by clang 4+. |
26 | here generates easier-to-read diagnostics when verify (R) fails. | ||
27 | 26 | ||
28 | Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11. | 27 | Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as |
29 | This will likely be supported by future GCC versions, in C++ mode. | 28 | per C2x. This is supported by GCC 9.1+. |
30 | 29 | ||
31 | Use this only with GCC. If we were willing to slow 'configure' | 30 | Support compilers claiming conformance to the relevant standard, |
32 | down we could also use it with other compilers, but since this | 31 | and also support GCC when not pedantic. If we were willing to slow |
33 | affects only the quality of diagnostics, why bother? */ | 32 | 'configure' down we could also use it with other compilers, but |
34 | #if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \ | 33 | since this affects only the quality of diagnostics, why bother? */ |
35 | && (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \ | 34 | #ifndef __cplusplus |
36 | && !defined __cplusplus) | 35 | # if (201112L <= __STDC_VERSION__ \ |
37 | # define _GL_HAVE__STATIC_ASSERT 1 | 36 | || (!defined __STRICT_ANSI__ \ |
38 | #endif | 37 | && (4 < __GNUC__ + (6 <= __GNUC_MINOR__) || 5 <= __clang_major__))) |
39 | /* The condition (99 < __GNUC__) is temporary, until we know about the | 38 | # define _GL_HAVE__STATIC_ASSERT 1 |
40 | first G++ release that supports static_assert. */ | 39 | # endif |
41 | #if (99 < __GNUC__) && defined __cplusplus | 40 | # if (202000L <= __STDC_VERSION__ \ |
42 | # define _GL_HAVE_STATIC_ASSERT 1 | 41 | || (!defined __STRICT_ANSI__ && 9 <= __GNUC__)) |
42 | # define _GL_HAVE__STATIC_ASSERT1 1 | ||
43 | # endif | ||
43 | #endif | 44 | #endif |
44 | 45 | ||
45 | /* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other | 46 | /* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other |
46 | system headers, defines a conflicting _Static_assert that is no | 47 | system headers, defines a conflicting _Static_assert that is no |
47 | better than ours; override it. */ | 48 | better than ours; override it. */ |
48 | #ifndef _GL_HAVE_STATIC_ASSERT | 49 | #ifndef _GL_HAVE__STATIC_ASSERT |
49 | # include <stddef.h> | 50 | # include <stddef.h> |
50 | # undef _Static_assert | 51 | # undef _Static_assert |
51 | #endif | 52 | #endif |
@@ -143,9 +144,9 @@ | |||
143 | which do not support _Static_assert, also do not warn about the | 144 | which do not support _Static_assert, also do not warn about the |
144 | last declaration mentioned above. | 145 | last declaration mentioned above. |
145 | 146 | ||
146 | * GCC warns if -Wnested-externs is enabled and verify() is used | 147 | * GCC warns if -Wnested-externs is enabled and 'verify' is used |
147 | within a function body; but inside a function, you can always | 148 | within a function body; but inside a function, you can always |
148 | arrange to use verify_expr() instead. | 149 | arrange to use verify_expr instead. |
149 | 150 | ||
150 | * In C++, any struct definition inside sizeof is invalid. | 151 | * In C++, any struct definition inside sizeof is invalid. |
151 | Use a template type to work around the problem. */ | 152 | Use a template type to work around the problem. */ |
@@ -197,48 +198,66 @@ template <int w> | |||
197 | #endif | 198 | #endif |
198 | 199 | ||
199 | /* Verify requirement R at compile-time, as a declaration without a | 200 | /* Verify requirement R at compile-time, as a declaration without a |
200 | trailing ';'. If R is false, fail at compile-time, preferably | 201 | trailing ';'. If R is false, fail at compile-time. |
201 | with a diagnostic that includes the string-literal DIAGNOSTIC. | 202 | |
203 | This macro requires three or more arguments but uses at most the first | ||
204 | two, so that the _Static_assert macro optionally defined below supports | ||
205 | both the C11 two-argument syntax and the C2x one-argument syntax. | ||
202 | 206 | ||
203 | Unfortunately, unlike C11, this implementation must appear as an | 207 | Unfortunately, unlike C11, this implementation must appear as an |
204 | ordinary declaration, and cannot appear inside struct { ... }. */ | 208 | ordinary declaration, and cannot appear inside struct { ... }. */ |
205 | 209 | ||
206 | #ifdef _GL_HAVE__STATIC_ASSERT | 210 | #if 200410 <= __cpp_static_assert |
207 | # define _GL_VERIFY _Static_assert | 211 | # define _GL_VERIFY(R, DIAGNOSTIC, ...) static_assert (R, DIAGNOSTIC) |
212 | #elif defined _GL_HAVE__STATIC_ASSERT | ||
213 | # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC) | ||
208 | #else | 214 | #else |
209 | # define _GL_VERIFY(R, DIAGNOSTIC) \ | 215 | # define _GL_VERIFY(R, DIAGNOSTIC, ...) \ |
210 | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ | 216 | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ |
211 | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] | 217 | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] |
218 | # if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) | ||
219 | # pragma GCC diagnostic ignored "-Wnested-externs" | ||
220 | # endif | ||
212 | #endif | 221 | #endif |
213 | 222 | ||
214 | /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ | 223 | /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ |
215 | #ifdef _GL_STATIC_ASSERT_H | 224 | #ifdef _GL_STATIC_ASSERT_H |
216 | # if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert | 225 | # if !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert |
217 | # define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) | 226 | # define _Static_assert(...) \ |
227 | _GL_VERIFY (__VA_ARGS__, "static assertion failed", -) | ||
218 | # endif | 228 | # endif |
219 | # if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert | 229 | # if __cpp_static_assert < 201411 && !defined static_assert |
220 | # define static_assert _Static_assert /* C11 requires this #define. */ | 230 | # define static_assert _Static_assert /* C11 requires this #define. */ |
221 | # endif | 231 | # endif |
222 | #endif | 232 | #endif |
223 | 233 | ||
224 | /* @assert.h omit start@ */ | 234 | /* @assert.h omit start@ */ |
225 | 235 | ||
236 | #if 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)) | ||
237 | # define _GL_HAS_BUILTIN_TRAP 1 | ||
238 | #elif defined __has_builtin | ||
239 | # define _GL_HAS_BUILTIN_TRAP __has_builtin (__builtin_trap) | ||
240 | #else | ||
241 | # define _GL_HAS_BUILTIN_TRAP 0 | ||
242 | #endif | ||
243 | |||
244 | #if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) | ||
245 | # define _GL_HAS_BUILTIN_UNREACHABLE 1 | ||
246 | #elif defined __has_builtin | ||
247 | # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) | ||
248 | #else | ||
249 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | ||
250 | #endif | ||
251 | |||
226 | /* Each of these macros verifies that its argument R is nonzero. To | 252 | /* Each of these macros verifies that its argument R is nonzero. To |
227 | be portable, R should be an integer constant expression. Unlike | 253 | be portable, R should be an integer constant expression. Unlike |
228 | assert (R), there is no run-time overhead. | 254 | assert (R), there is no run-time overhead. |
229 | 255 | ||
230 | There are two macros, since no single macro can be used in all | 256 | There are two macros, since no single macro can be used in all |
231 | contexts in C. verify_true (R) is for scalar contexts, including | 257 | contexts in C. verify_expr (R, E) is for scalar contexts, including |
232 | integer constant expression contexts. verify (R) is for declaration | 258 | integer constant expression contexts. verify (R) is for declaration |
233 | contexts, e.g., the top level. */ | 259 | contexts, e.g., the top level. */ |
234 | 260 | ||
235 | /* Verify requirement R at compile-time, as an integer constant expression. | ||
236 | Return 1. This is equivalent to verify_expr (R, 1). | ||
237 | |||
238 | verify_true is obsolescent; please use verify_expr instead. */ | ||
239 | |||
240 | #define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") | ||
241 | |||
242 | /* Verify requirement R at compile-time. Return the value of the | 261 | /* Verify requirement R at compile-time. Return the value of the |
243 | expression E. */ | 262 | expression E. */ |
244 | 263 | ||
@@ -246,9 +265,56 @@ template <int w> | |||
246 | (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) | 265 | (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) |
247 | 266 | ||
248 | /* Verify requirement R at compile-time, as a declaration without a | 267 | /* Verify requirement R at compile-time, as a declaration without a |
249 | trailing ';'. */ | 268 | trailing ';'. verify (R) acts like static_assert (R) except that |
269 | it is portable to C11/C++14 and earlier, it can issue better | ||
270 | diagnostics, and its name is shorter and may be more convenient. */ | ||
271 | |||
272 | #ifdef __PGI | ||
273 | /* PGI barfs if R is long. */ | ||
274 | # define verify(R) _GL_VERIFY (R, "verify (...)", -) | ||
275 | #else | ||
276 | # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) | ||
277 | #endif | ||
250 | 278 | ||
251 | #define verify(R) _GL_VERIFY (R, "verify (" #R ")") | 279 | /* Assume that R always holds. Behavior is undefined if R is false, |
280 | fails to evaluate, or has side effects. | ||
281 | |||
282 | 'assume (R)' is a directive from the programmer telling the | ||
283 | compiler that R is true so the compiler needn't generate code to | ||
284 | test R. This is why 'assume' is in verify.h: it's related to | ||
285 | static checking (in this case, static checking done by the | ||
286 | programmer), not dynamic checking. | ||
287 | |||
288 | 'assume (R)' can affect compilation of all the code, not just code | ||
289 | that happens to be executed after the assume (R) is "executed". | ||
290 | For example, if the code mistakenly does 'assert (R); assume (R);' | ||
291 | the compiler is entitled to optimize away the 'assert (R)'. | ||
292 | |||
293 | Although assuming R can help a compiler generate better code or | ||
294 | diagnostics, performance can suffer if R uses hard-to-optimize | ||
295 | features such as function calls not inlined by the compiler. | ||
296 | |||
297 | Avoid Clang's __builtin_assume, as it breaks GNU Emacs master | ||
298 | as of 2020-08-23T21:09:49Z!eggert@cs.ucla.edu; see | ||
299 | <https://bugs.gnu.org/43152#71>. It's not known whether this breakage | ||
300 | is a Clang bug or an Emacs bug; play it safe for now. */ | ||
301 | |||
302 | #if _GL_HAS_BUILTIN_UNREACHABLE | ||
303 | # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) | ||
304 | #elif 1200 <= _MSC_VER | ||
305 | # define assume(R) __assume (R) | ||
306 | #elif 202311L <= __STDC_VERSION__ | ||
307 | # include <stddef.h> | ||
308 | # define assume(R) ((R) ? (void) 0 : unreachable ()) | ||
309 | #elif (defined GCC_LINT || defined lint) && _GL_HAS_BUILTIN_TRAP | ||
310 | /* Doing it this way helps various packages when configured with | ||
311 | --enable-gcc-warnings, which compiles with -Dlint. It's nicer | ||
312 | if 'assume' silences warnings with GCC 3.4 through GCC 4.4.7 (2012). */ | ||
313 | # define assume(R) ((R) ? (void) 0 : __builtin_trap ()) | ||
314 | #else | ||
315 | /* Some older tools grok NOTREACHED, e.g., Oracle Studio 12.6 (2017). */ | ||
316 | # define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0) | ||
317 | #endif | ||
252 | 318 | ||
253 | /* @assert.h omit end@ */ | 319 | /* @assert.h omit end@ */ |
254 | 320 | ||