|
version 1.1.1.1, 2012/05/29 09:29:43
|
version 1.1.1.2, 2021/03/17 13:38:46
|
|
Line 1
|
Line 1
|
| /* Compile-time assert-like macros. |
/* Compile-time assert-like macros. |
| |
|
| Copyright (C) 2005-2006, 2009-2011 Free Software Foundation, Inc. | Copyright (C) 2005-2006, 2009-2019 Free Software Foundation, Inc. |
| |
|
| This program is free software: you can redistribute it and/or modify |
This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
|
Line 13
|
Line 13
|
| GNU General Public License for more details. |
GNU General Public License for more details. |
| |
|
| You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. */ | along with this program. If not, see <https://www.gnu.org/licenses/>. */ |
| |
|
| /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ |
/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ |
| |
|
| #ifndef _GL_VERIFY_H |
#ifndef _GL_VERIFY_H |
| # define _GL_VERIFY_H | #define _GL_VERIFY_H |
| |
|
| |
|
| /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per the | /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11. |
| C1X draft N1548 section 6.7.10. This is supported by GCC 4.6.0 and | This is supported by GCC 4.6.0 and later, in C mode, and its use |
| later, in C mode, and its use here generates easier-to-read diagnostics | here generates easier-to-read diagnostics when verify (R) fails. |
| when verify (R) fails. | |
| |
|
| Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per the | Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11. |
| C++0X draft N3242 section 7.(4). | This is supported by GCC 6.1.0 and later, in C++ mode. |
| This will likely be supported by future GCC versions, in C++ mode. | |
| |
|
| Use this only with GCC. If we were willing to slow 'configure' |
Use this only with GCC. If we were willing to slow 'configure' |
| down we could also use it with other compilers, but since this |
down we could also use it with other compilers, but since this |
| affects only the quality of diagnostics, why bother? */ |
affects only the quality of diagnostics, why bother? */ |
| # if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus | #if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \ |
| # define _GL_HAVE__STATIC_ASSERT 1 | && (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \ |
| # endif | && !defined __cplusplus) |
| /* The condition (99 < __GNUC__) is temporary, until we know about the | # define _GL_HAVE__STATIC_ASSERT 1 |
| first G++ release that supports static_assert. */ | #endif |
| # if (99 < __GNUC__) && defined __cplusplus | #if (6 <= __GNUC__) && defined __cplusplus |
| # define _GL_HAVE_STATIC_ASSERT 1 | # define _GL_HAVE_STATIC_ASSERT 1 |
| # endif | #endif |
| |
|
| |
/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other |
| |
system headers, defines a conflicting _Static_assert that is no |
| |
better than ours; override it. */ |
| |
#ifndef _GL_HAVE_STATIC_ASSERT |
| |
# include <stddef.h> |
| |
# undef _Static_assert |
| |
#endif |
| |
|
| /* Each of these macros verifies that its argument R is nonzero. To |
/* Each of these macros verifies that its argument R is nonzero. To |
| be portable, R should be an integer constant expression. Unlike |
be portable, R should be an integer constant expression. Unlike |
| assert (R), there is no run-time overhead. |
assert (R), there is no run-time overhead. |
|
Line 127
|
Line 133
|
| extern int (*dummy (void)) [sizeof (struct {...})]; |
extern int (*dummy (void)) [sizeof (struct {...})]; |
| |
|
| * GCC warns about duplicate declarations of the dummy function if |
* GCC warns about duplicate declarations of the dummy function if |
| -Wredundant_decls is used. GCC 4.3 and later have a builtin | -Wredundant-decls is used. GCC 4.3 and later have a builtin |
| __COUNTER__ macro that can let us generate unique identifiers for |
__COUNTER__ macro that can let us generate unique identifiers for |
| each dummy function, to suppress this warning. |
each dummy function, to suppress this warning. |
| |
|
|
Line 135
|
Line 141
|
| which do not support _Static_assert, also do not warn about the |
which do not support _Static_assert, also do not warn about the |
| last declaration mentioned above. |
last declaration mentioned above. |
| |
|
| |
* GCC warns if -Wnested-externs is enabled and verify() is used |
| |
within a function body; but inside a function, you can always |
| |
arrange to use verify_expr() instead. |
| |
|
| * In C++, any struct definition inside sizeof is invalid. |
* In C++, any struct definition inside sizeof is invalid. |
| Use a template type to work around the problem. */ |
Use a template type to work around the problem. */ |
| |
|
| /* Concatenate two preprocessor tokens. */ |
/* Concatenate two preprocessor tokens. */ |
| # define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) | #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) |
| # define _GL_CONCAT0(x, y) x##y | #define _GL_CONCAT0(x, y) x##y |
| |
|
| /* _GL_COUNTER is an integer, preferably one that changes each time we |
/* _GL_COUNTER is an integer, preferably one that changes each time we |
| use it. Use __COUNTER__ if it works, falling back on __LINE__ |
use it. Use __COUNTER__ if it works, falling back on __LINE__ |
| otherwise. __LINE__ isn't perfect, but it's better than a |
otherwise. __LINE__ isn't perfect, but it's better than a |
| constant. */ |
constant. */ |
| # if defined __COUNTER__ && __COUNTER__ != __COUNTER__ | #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ |
| # define _GL_COUNTER __COUNTER__ | # define _GL_COUNTER __COUNTER__ |
| # else | #else |
| # define _GL_COUNTER __LINE__ | # define _GL_COUNTER __LINE__ |
| # endif | #endif |
| |
|
| /* Generate a symbol with the given prefix, making it unique if |
/* Generate a symbol with the given prefix, making it unique if |
| possible. */ |
possible. */ |
| # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) | #define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) |
| |
|
| /* Verify requirement R at compile-time, as an integer constant expression |
/* Verify requirement R at compile-time, as an integer constant expression |
| that returns 1. If R is false, fail at compile-time, preferably |
that returns 1. If R is false, fail at compile-time, preferably |
| with a diagnostic that includes the string-literal DIAGNOSTIC. */ |
with a diagnostic that includes the string-literal DIAGNOSTIC. */ |
| |
|
| # define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ | #define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ |
| (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) | (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) |
| |
|
| # ifdef __cplusplus | #ifdef __cplusplus |
| # if !GNULIB_defined_struct__gl_verify_type | # if !GNULIB_defined_struct__gl_verify_type |
| template <int w> |
template <int w> |
| struct _gl_verify_type { |
struct _gl_verify_type { |
| unsigned int _gl_verify_error_if_negative: w; |
unsigned int _gl_verify_error_if_negative: w; |
| }; |
}; |
| # define GNULIB_defined_struct__gl_verify_type 1 | # define GNULIB_defined_struct__gl_verify_type 1 |
| # endif | |
| # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | |
| _gl_verify_type<(R) ? 1 : -1> | |
| # elif defined _GL_HAVE__STATIC_ASSERT | |
| # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | |
| struct { \ | |
| _Static_assert (R, DIAGNOSTIC); \ | |
| int _gl_dummy; \ | |
| } | |
| # else | |
| # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ | |
| struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } | |
| # endif |
# endif |
| |
# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
| |
_gl_verify_type<(R) ? 1 : -1> |
| |
#elif defined _GL_HAVE__STATIC_ASSERT |
| |
# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
| |
struct { \ |
| |
_Static_assert (R, DIAGNOSTIC); \ |
| |
int _gl_dummy; \ |
| |
} |
| |
#else |
| |
# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
| |
struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } |
| |
#endif |
| |
|
| /* Verify requirement R at compile-time, as a declaration without a |
/* Verify requirement R at compile-time, as a declaration without a |
| trailing ';'. If R is false, fail at compile-time, preferably |
trailing ';'. If R is false, fail at compile-time, preferably |
| with a diagnostic that includes the string-literal DIAGNOSTIC. |
with a diagnostic that includes the string-literal DIAGNOSTIC. |
| |
|
| Unfortunately, unlike C1X, this implementation must appear as an | Unfortunately, unlike C11, this implementation must appear as an |
| ordinary declaration, and cannot appear inside struct { ... }. */ |
ordinary declaration, and cannot appear inside struct { ... }. */ |
| |
|
| # ifdef _GL_HAVE__STATIC_ASSERT | #ifdef _GL_HAVE__STATIC_ASSERT |
| # define _GL_VERIFY _Static_assert | # define _GL_VERIFY _Static_assert |
| # else | #else |
| # define _GL_VERIFY(R, DIAGNOSTIC) \ | # define _GL_VERIFY(R, DIAGNOSTIC) \ |
| extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ |
| [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] |
| # endif | #endif |
| |
|
| /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ |
/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ |
| # ifdef _GL_STATIC_ASSERT_H | #ifdef _GL_STATIC_ASSERT_H |
| # if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert | # if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert |
| # define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) | # define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) |
| # endif | |
| # if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert | |
| # define static_assert _Static_assert /* Draft C1X requires this #define. */ | |
| # endif | |
| # endif |
# endif |
| |
# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert |
| |
# define static_assert _Static_assert /* C11 requires this #define. */ |
| |
# endif |
| |
#endif |
| |
|
| /* @assert.h omit start@ */ |
/* @assert.h omit start@ */ |
| |
|
|
Line 225 template <int w>
|
Line 235 template <int w>
|
| |
|
| verify_true is obsolescent; please use verify_expr instead. */ |
verify_true is obsolescent; please use verify_expr instead. */ |
| |
|
| # define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") | #define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") |
| |
|
| /* Verify requirement R at compile-time. Return the value of the |
/* Verify requirement R at compile-time. Return the value of the |
| expression E. */ |
expression E. */ |
| |
|
| # define verify_expr(R, E) \ | #define verify_expr(R, E) \ |
| (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) | (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) |
| |
|
| /* Verify requirement R at compile-time, as a declaration without a |
/* Verify requirement R at compile-time, as a declaration without a |
| trailing ';'. */ |
trailing ';'. */ |
| |
|
| |
#ifdef __GNUC__ |
| # define verify(R) _GL_VERIFY (R, "verify (" #R ")") |
# define verify(R) _GL_VERIFY (R, "verify (" #R ")") |
| |
#else |
| |
/* PGI barfs if R is long. Play it safe. */ |
| |
# define verify(R) _GL_VERIFY (R, "verify (...)") |
| |
#endif |
| |
|
| |
#ifndef __has_builtin |
| |
# define __has_builtin(x) 0 |
| |
#endif |
| |
|
| |
/* Assume that R always holds. This lets the compiler optimize |
| |
accordingly. R should not have side-effects; it may or may not be |
| |
evaluated. Behavior is undefined if R is false. */ |
| |
|
| |
#if (__has_builtin (__builtin_unreachable) \ |
| |
|| 4 < __GNUC__ + (5 <= __GNUC_MINOR__)) |
| |
# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) |
| |
#elif 1200 <= _MSC_VER |
| |
# define assume(R) __assume (R) |
| |
#elif ((defined GCC_LINT || defined lint) \ |
| |
&& (__has_builtin (__builtin_trap) \ |
| |
|| 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)))) |
| |
/* Doing it this way helps various packages when configured with |
| |
--enable-gcc-warnings, which compiles with -Dlint. It's nicer |
| |
when 'assume' silences warnings even with older GCCs. */ |
| |
# define assume(R) ((R) ? (void) 0 : __builtin_trap ()) |
| |
#else |
| |
/* Some tools grok NOTREACHED, e.g., Oracle Studio 12.6. */ |
| |
# define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0) |
| |
#endif |
| |
|
| /* @assert.h omit end@ */ |
/* @assert.h omit end@ */ |
| |
|