diff options
author | Kristian Schuster <116557017+KriSchu@users.noreply.github.com> | 2023-02-19 23:49:18 +0100 |
---|---|---|
committer | Kristian Schuster <116557017+KriSchu@users.noreply.github.com> | 2023-02-19 23:49:18 +0100 |
commit | a0d42777217296c0a7bdb1e1be8d8f6de1b24dd7 (patch) | |
tree | 8effe94c57b2f9796ba36090b07551baa8f1e1cb /gl/verify.h | |
parent | ca3d59cd6918c9e2739e783b721d4c1122640fd3 (diff) | |
parent | c07206f2ccc2356aa74bc6813a94c2190017d44e (diff) | |
download | monitoring-plugins-a0d4277.tar.gz |
Merge remote-tracking branch 'origin/master' into feature_check_disk_add_ignore_missing_option
Diffstat (limited to 'gl/verify.h')
-rw-r--r-- | gl/verify.h | 191 |
1 files changed, 143 insertions, 48 deletions
diff --git a/gl/verify.h b/gl/verify.h index d42d0750..b63cb264 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-2023 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 C23. 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 (201112 <= __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 (202311 <= __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,95 @@ 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 C23 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 202311 <= __STDC_VERSION__ || 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 | # if !defined _MSC_VER || defined __clang__ |
227 | # define _Static_assert(...) \ | ||
228 | _GL_VERIFY (__VA_ARGS__, "static assertion failed", -) | ||
229 | # else | ||
230 | /* Work around MSVC preprocessor incompatibility with ISO C; see | ||
231 | <https://stackoverflow.com/questions/5134523/>. */ | ||
232 | # define _Static_assert(R, ...) \ | ||
233 | _GL_VERIFY ((R), "static assertion failed", -) | ||
234 | # endif | ||
218 | # endif | 235 | # endif |
219 | # if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert | 236 | # if (!defined static_assert \ |
220 | # define static_assert _Static_assert /* C11 requires this #define. */ | 237 | && __STDC_VERSION__ < 202311 \ |
238 | && (!defined __cplusplus \ | ||
239 | || (__cpp_static_assert < 201411 \ | ||
240 | && __GNUG__ < 6 && __clang_major__ < 6))) | ||
241 | # if defined __cplusplus && _MSC_VER >= 1900 && !defined __clang__ | ||
242 | /* 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. | ||
244 | We have to play preprocessor tricks to distinguish the two cases. | ||
245 | Since the MSVC preprocessor is not ISO C compliant (see above),. | ||
246 | the solution is specific to MSVC. */ | ||
247 | # define _GL_EXPAND(x) x | ||
248 | # define _GL_SA1(a1) static_assert ((a1), "static assertion failed") | ||
249 | # define _GL_SA2 static_assert | ||
250 | # define _GL_SA3 static_assert | ||
251 | # 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__) | ||
253 | # else | ||
254 | # define static_assert _Static_assert /* C11 requires this #define. */ | ||
255 | # endif | ||
221 | # endif | 256 | # endif |
222 | #endif | 257 | #endif |
223 | 258 | ||
224 | /* @assert.h omit start@ */ | 259 | /* @assert.h omit start@ */ |
225 | 260 | ||
261 | #if defined __clang_major__ && __clang_major__ < 5 | ||
262 | # define _GL_HAS_BUILTIN_TRAP 0 | ||
263 | #elif 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)) | ||
264 | # define _GL_HAS_BUILTIN_TRAP 1 | ||
265 | #elif defined __has_builtin | ||
266 | # define _GL_HAS_BUILTIN_TRAP __has_builtin (__builtin_trap) | ||
267 | #else | ||
268 | # define _GL_HAS_BUILTIN_TRAP 0 | ||
269 | #endif | ||
270 | |||
271 | #if defined __clang_major__ && __clang_major__ < 5 | ||
272 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | ||
273 | #elif 4 < __GNUC__ + (5 <= __GNUC_MINOR__) | ||
274 | # define _GL_HAS_BUILTIN_UNREACHABLE 1 | ||
275 | #elif defined __has_builtin | ||
276 | # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable) | ||
277 | #else | ||
278 | # define _GL_HAS_BUILTIN_UNREACHABLE 0 | ||
279 | #endif | ||
280 | |||
226 | /* Each of these macros verifies that its argument R is nonzero. To | 281 | /* Each of these macros verifies that its argument R is nonzero. To |
227 | be portable, R should be an integer constant expression. Unlike | 282 | be portable, R should be an integer constant expression. Unlike |
228 | assert (R), there is no run-time overhead. | 283 | assert (R), there is no run-time overhead. |
229 | 284 | ||
230 | There are two macros, since no single macro can be used in all | 285 | 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 | 286 | contexts in C. verify_expr (R, E) is for scalar contexts, including |
232 | integer constant expression contexts. verify (R) is for declaration | 287 | integer constant expression contexts. verify (R) is for declaration |
233 | contexts, e.g., the top level. */ | 288 | contexts, e.g., the top level. */ |
234 | 289 | ||
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 | 290 | /* Verify requirement R at compile-time. Return the value of the |
243 | expression E. */ | 291 | expression E. */ |
244 | 292 | ||
@@ -246,9 +294,56 @@ template <int w> | |||
246 | (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) | 294 | (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) |
247 | 295 | ||
248 | /* Verify requirement R at compile-time, as a declaration without a | 296 | /* Verify requirement R at compile-time, as a declaration without a |
249 | trailing ';'. */ | 297 | trailing ';'. verify (R) acts like static_assert (R) except that |
298 | it is portable to C11/C++14 and earlier, it can issue better | ||
299 | diagnostics, and its name is shorter and may be more convenient. */ | ||
300 | |||
301 | #ifdef __PGI | ||
302 | /* PGI barfs if R is long. */ | ||
303 | # define verify(R) _GL_VERIFY (R, "verify (...)", -) | ||
304 | #else | ||
305 | # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -) | ||
306 | #endif | ||
250 | 307 | ||
251 | #define verify(R) _GL_VERIFY (R, "verify (" #R ")") | 308 | /* Assume that R always holds. Behavior is undefined if R is false, |
309 | fails to evaluate, or has side effects. | ||
310 | |||
311 | 'assume (R)' is a directive from the programmer telling the | ||
312 | compiler that R is true so the compiler needn't generate code to | ||
313 | test R. This is why 'assume' is in verify.h: it's related to | ||
314 | static checking (in this case, static checking done by the | ||
315 | programmer), not dynamic checking. | ||
316 | |||
317 | 'assume (R)' can affect compilation of all the code, not just code | ||
318 | that happens to be executed after the assume (R) is "executed". | ||
319 | For example, if the code mistakenly does 'assert (R); assume (R);' | ||
320 | the compiler is entitled to optimize away the 'assert (R)'. | ||
321 | |||
322 | Although assuming R can help a compiler generate better code or | ||
323 | diagnostics, performance can suffer if R uses hard-to-optimize | ||
324 | features such as function calls not inlined by the compiler. | ||
325 | |||
326 | Avoid Clang's __builtin_assume, as it breaks GNU Emacs master | ||
327 | as of 2020-08-23T21:09:49Z!eggert@cs.ucla.edu; see | ||
328 | <https://bugs.gnu.org/43152#71>. It's not known whether this breakage | ||
329 | is a Clang bug or an Emacs bug; play it safe for now. */ | ||
330 | |||
331 | #if _GL_HAS_BUILTIN_UNREACHABLE | ||
332 | # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) | ||
333 | #elif 1200 <= _MSC_VER | ||
334 | # define assume(R) __assume (R) | ||
335 | #elif 202311 <= __STDC_VERSION__ | ||
336 | # include <stddef.h> | ||
337 | # define assume(R) ((R) ? (void) 0 : unreachable ()) | ||
338 | #elif (defined GCC_LINT || defined lint) && _GL_HAS_BUILTIN_TRAP | ||
339 | /* Doing it this way helps various packages when configured with | ||
340 | --enable-gcc-warnings, which compiles with -Dlint. It's nicer | ||
341 | if 'assume' silences warnings with GCC 3.4 through GCC 4.4.7 (2012). */ | ||
342 | # define assume(R) ((R) ? (void) 0 : __builtin_trap ()) | ||
343 | #else | ||
344 | /* Some older tools grok NOTREACHED, e.g., Oracle Studio 12.6 (2017). */ | ||
345 | # define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0) | ||
346 | #endif | ||
252 | 347 | ||
253 | /* @assert.h omit end@ */ | 348 | /* @assert.h omit end@ */ |
254 | 349 | ||