diff options
Diffstat (limited to 'gl/verify.h')
| -rw-r--r-- | gl/verify.h | 154 | 
1 files changed, 107 insertions, 47 deletions
| diff --git a/gl/verify.h b/gl/verify.h index d42d0750..a8ca59b0 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-2021 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__) || 4 <= __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,63 @@ 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)] | 
| 212 | #endif | 218 | #endif | 
| 213 | 219 | ||
| 214 | /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ | 220 | /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ | 
| 215 | #ifdef _GL_STATIC_ASSERT_H | 221 | #ifdef _GL_STATIC_ASSERT_H | 
| 216 | # if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert | 222 | # if !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert | 
| 217 | # define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) | 223 | # define _Static_assert(...) \ | 
| 224 | _GL_VERIFY (__VA_ARGS__, "static assertion failed", -) | ||
| 218 | # endif | 225 | # endif | 
| 219 | # if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert | 226 | # if __cpp_static_assert < 201411 && !defined static_assert | 
| 220 | # define static_assert _Static_assert /* C11 requires this #define. */ | 227 | # define static_assert _Static_assert /* C11 requires this #define. */ | 
| 221 | # endif | 228 | # endif | 
| 222 | #endif | 229 | #endif | 
| 223 | 230 | ||
| 224 | /* @assert.h omit start@ */ | 231 | /* @assert.h omit start@ */ | 
| 225 | 232 | ||
| 233 | #if 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)) | ||
| 234 | # define _GL_HAS_BUILTIN_TRAP 1 | ||
| 235 | #elif defined __has_builtin | ||
| 236 | # define _GL_HAS_BUILTIN_TRAP __has_builtin (__builtin_trap) | ||
| 237 | #else | ||
| 238 | # define _GL_HAS_BUILTIN_TRAP 0 | ||
| 239 | #endif | ||
| 240 | |||
| 241 | #if 4 < __GNUC__ + (5 <= __GNUC_MINOR__) | ||
| 242 | # define _GL_HAS_BUILTIN_UNREACHABLE 1 | ||
| 243 | #elif defined __has_builtin | ||
| 244 | # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) | ||
| 245 | #else | ||
| 246 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | ||
| 247 | #endif | ||
| 248 | |||
| 226 | /* Each of these macros verifies that its argument R is nonzero. To | 249 | /* Each of these macros verifies that its argument R is nonzero. To | 
| 227 | be portable, R should be an integer constant expression. Unlike | 250 | be portable, R should be an integer constant expression. Unlike | 
| 228 | assert (R), there is no run-time overhead. | 251 | assert (R), there is no run-time overhead. | 
| 229 | 252 | ||
| 230 | There are two macros, since no single macro can be used in all | 253 | 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 | 254 | contexts in C. verify_expr (R, E) is for scalar contexts, including | 
| 232 | integer constant expression contexts. verify (R) is for declaration | 255 | integer constant expression contexts. verify (R) is for declaration | 
| 233 | contexts, e.g., the top level. */ | 256 | contexts, e.g., the top level. */ | 
| 234 | 257 | ||
| 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 | 258 | /* Verify requirement R at compile-time. Return the value of the | 
| 243 | expression E. */ | 259 | expression E. */ | 
| 244 | 260 | ||
| @@ -246,9 +262,53 @@ template <int w> | |||
| 246 | (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) | 262 | (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) | 
| 247 | 263 | ||
| 248 | /* Verify requirement R at compile-time, as a declaration without a | 264 | /* Verify requirement R at compile-time, as a declaration without a | 
| 249 | trailing ';'. */ | 265 | trailing ';'. verify (R) acts like static_assert (R) except that | 
| 266 | it is portable to C11/C++14 and earlier, it can issue better | ||
| 267 | diagnostics, and its name is shorter and may be more convenient. */ | ||
| 250 | 268 | ||
| 251 | #define verify(R) _GL_VERIFY (R, "verify (" #R ")") | 269 | #ifdef __PGI | 
| 270 | /* PGI barfs if R is long. */ | ||
| 271 | # define verify(R) _GL_VERIFY (R, "verify (...)", -) | ||
| 272 | #else | ||
| 273 | # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) | ||
| 274 | #endif | ||
| 275 | |||
| 276 | /* Assume that R always holds. Behavior is undefined if R is false, | ||
| 277 | fails to evaluate, or has side effects. | ||
| 278 | |||
| 279 | 'assume (R)' is a directive from the programmer telling the | ||
| 280 | compiler that R is true so the compiler needn't generate code to | ||
| 281 | test R. This is why 'assume' is in verify.h: it's related to | ||
| 282 | static checking (in this case, static checking done by the | ||
| 283 | programmer), not dynamic checking. | ||
| 284 | |||
| 285 | 'assume (R)' can affect compilation of all the code, not just code | ||
| 286 | that happens to be executed after the assume (R) is "executed". | ||
| 287 | For example, if the code mistakenly does 'assert (R); assume (R);' | ||
| 288 | the compiler is entitled to optimize away the 'assert (R)'. | ||
| 289 | |||
| 290 | Although assuming R can help a compiler generate better code or | ||
| 291 | diagnostics, performance can suffer if R uses hard-to-optimize | ||
| 292 | features such as function calls not inlined by the compiler. | ||
| 293 | |||
| 294 | Avoid Clang's __builtin_assume, as it breaks GNU Emacs master | ||
| 295 | as of 2020-08-23T21:09:49Z!eggert@cs.ucla.edu; see | ||
| 296 | <https://bugs.gnu.org/43152#71>. It's not known whether this breakage | ||
| 297 | is a Clang bug or an Emacs bug; play it safe for now. */ | ||
| 298 | |||
| 299 | #if _GL_HAS_BUILTIN_UNREACHABLE | ||
| 300 | # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) | ||
| 301 | #elif 1200 <= _MSC_VER | ||
| 302 | # define assume(R) __assume (R) | ||
| 303 | #elif (defined GCC_LINT || defined lint) && _GL_HAS_BUILTIN_TRAP | ||
| 304 | /* Doing it this way helps various packages when configured with | ||
| 305 | --enable-gcc-warnings, which compiles with -Dlint. It's nicer | ||
| 306 | when 'assume' silences warnings even with older GCCs. */ | ||
| 307 | # define assume(R) ((R) ? (void) 0 : __builtin_trap ()) | ||
| 308 | #else | ||
| 309 | /* Some tools grok NOTREACHED, e.g., Oracle Studio 12.6. */ | ||
| 310 | # define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0) | ||
| 311 | #endif | ||
| 252 | 312 | ||
| 253 | /* @assert.h omit end@ */ | 313 | /* @assert.h omit end@ */ | 
| 254 | 314 | ||
