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@ */ |
|
|