"Fossies" - the Fresh Open Source Software Archive

Member "gawk-5.1.0/support/verify.h" (6 Feb 2020, 11598 Bytes) of package /linux/misc/gawk-5.1.0.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "verify.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.0.1_vs_5.1.0.

    1 /* Compile-time assert-like macros.
    2 
    3    Copyright (C) 2005-2006, 2009-2019 Free Software Foundation, Inc.
    4 
    5    This program is free software: you can redistribute it and/or modify
    6    it under the terms of the GNU General Public License as published by
    7    the Free Software Foundation; either version 3 of the License, or
    8    (at your option) any later version.
    9 
   10    This program is distributed in the hope that it will be useful,
   11    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13    GNU General Public License for more details.
   14 
   15    You should have received a copy of the GNU General Public License
   16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
   17 
   18 /* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */
   19 
   20 #ifndef _GL_VERIFY_H
   21 #define _GL_VERIFY_H
   22 
   23 
   24 /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC)
   25    works as per C11.  This is supported by GCC 4.6.0 and later, in C
   26    mode.
   27 
   28    Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as
   29    per C2X, and define _GL_HAVE_STATIC_ASSERT1 if static_assert (R)
   30    works as per C++17.  This is supported by GCC 9.1 and later.
   31 
   32    Support compilers claiming conformance to the relevant standard,
   33    and also support GCC when not pedantic.  If we were willing to slow
   34    'configure' down we could also use it with other compilers, but
   35    since this affects only the quality of diagnostics, why bother?  */
   36 #ifndef __cplusplus
   37 # if (201112L <= __STDC_VERSION__ \
   38       || (!defined __STRICT_ANSI__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)))
   39 #  define _GL_HAVE__STATIC_ASSERT 1
   40 # endif
   41 # if (202000L <= __STDC_VERSION__ \
   42       || (!defined __STRICT_ANSI__ && 9 <= __GNUC__))
   43 #  define _GL_HAVE__STATIC_ASSERT1 1
   44 # endif
   45 #else
   46 # if 201703L <= __cplusplus || 9 <= __GNUC__
   47 #  define _GL_HAVE_STATIC_ASSERT1 1
   48 # endif
   49 #endif
   50 
   51 /* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
   52    system headers, defines a conflicting _Static_assert that is no
   53    better than ours; override it.  */
   54 #ifndef _GL_HAVE__STATIC_ASSERT
   55 # include <stddef.h>
   56 # undef _Static_assert
   57 #endif
   58 
   59 /* Each of these macros verifies that its argument R is nonzero.  To
   60    be portable, R should be an integer constant expression.  Unlike
   61    assert (R), there is no run-time overhead.
   62 
   63    If _Static_assert works, verify (R) uses it directly.  Similarly,
   64    _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct
   65    that is an operand of sizeof.
   66 
   67    The code below uses several ideas for C++ compilers, and for C
   68    compilers that do not support _Static_assert:
   69 
   70    * The first step is ((R) ? 1 : -1).  Given an expression R, of
   71      integral or boolean or floating-point type, this yields an
   72      expression of integral type, whose value is later verified to be
   73      constant and nonnegative.
   74 
   75    * Next this expression W is wrapped in a type
   76      struct _gl_verify_type {
   77        unsigned int _gl_verify_error_if_negative: W;
   78      }.
   79      If W is negative, this yields a compile-time error.  No compiler can
   80      deal with a bit-field of negative size.
   81 
   82      One might think that an array size check would have the same
   83      effect, that is, that the type struct { unsigned int dummy[W]; }
   84      would work as well.  However, inside a function, some compilers
   85      (such as C++ compilers and GNU C) allow local parameters and
   86      variables inside array size expressions.  With these compilers,
   87      an array size check would not properly diagnose this misuse of
   88      the verify macro:
   89 
   90        void function (int n) { verify (n < 0); }
   91 
   92    * For the verify macro, the struct _gl_verify_type will need to
   93      somehow be embedded into a declaration.  To be portable, this
   94      declaration must declare an object, a constant, a function, or a
   95      typedef name.  If the declared entity uses the type directly,
   96      such as in
   97 
   98        struct dummy {...};
   99        typedef struct {...} dummy;
  100        extern struct {...} *dummy;
  101        extern void dummy (struct {...} *);
  102        extern struct {...} *dummy (void);
  103 
  104      two uses of the verify macro would yield colliding declarations
  105      if the entity names are not disambiguated.  A workaround is to
  106      attach the current line number to the entity name:
  107 
  108        #define _GL_CONCAT0(x, y) x##y
  109        #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
  110        extern struct {...} * _GL_CONCAT (dummy, __LINE__);
  111 
  112      But this has the problem that two invocations of verify from
  113      within the same macro would collide, since the __LINE__ value
  114      would be the same for both invocations.  (The GCC __COUNTER__
  115      macro solves this problem, but is not portable.)
  116 
  117      A solution is to use the sizeof operator.  It yields a number,
  118      getting rid of the identity of the type.  Declarations like
  119 
  120        extern int dummy [sizeof (struct {...})];
  121        extern void dummy (int [sizeof (struct {...})]);
  122        extern int (*dummy (void)) [sizeof (struct {...})];
  123 
  124      can be repeated.
  125 
  126    * Should the implementation use a named struct or an unnamed struct?
  127      Which of the following alternatives can be used?
  128 
  129        extern int dummy [sizeof (struct {...})];
  130        extern int dummy [sizeof (struct _gl_verify_type {...})];
  131        extern void dummy (int [sizeof (struct {...})]);
  132        extern void dummy (int [sizeof (struct _gl_verify_type {...})]);
  133        extern int (*dummy (void)) [sizeof (struct {...})];
  134        extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];
  135 
  136      In the second and sixth case, the struct type is exported to the
  137      outer scope; two such declarations therefore collide.  GCC warns
  138      about the first, third, and fourth cases.  So the only remaining
  139      possibility is the fifth case:
  140 
  141        extern int (*dummy (void)) [sizeof (struct {...})];
  142 
  143    * GCC warns about duplicate declarations of the dummy function if
  144      -Wredundant-decls is used.  GCC 4.3 and later have a builtin
  145      __COUNTER__ macro that can let us generate unique identifiers for
  146      each dummy function, to suppress this warning.
  147 
  148    * This implementation exploits the fact that older versions of GCC,
  149      which do not support _Static_assert, also do not warn about the
  150      last declaration mentioned above.
  151 
  152    * GCC warns if -Wnested-externs is enabled and 'verify' is used
  153      within a function body; but inside a function, you can always
  154      arrange to use verify_expr instead.
  155 
  156    * In C++, any struct definition inside sizeof is invalid.
  157      Use a template type to work around the problem.  */
  158 
  159 /* Concatenate two preprocessor tokens.  */
  160 #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
  161 #define _GL_CONCAT0(x, y) x##y
  162 
  163 /* _GL_COUNTER is an integer, preferably one that changes each time we
  164    use it.  Use __COUNTER__ if it works, falling back on __LINE__
  165    otherwise.  __LINE__ isn't perfect, but it's better than a
  166    constant.  */
  167 #if defined __COUNTER__ && __COUNTER__ != __COUNTER__
  168 # define _GL_COUNTER __COUNTER__
  169 #else
  170 # define _GL_COUNTER __LINE__
  171 #endif
  172 
  173 /* Generate a symbol with the given prefix, making it unique if
  174    possible.  */
  175 #define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
  176 
  177 /* Verify requirement R at compile-time, as an integer constant expression
  178    that returns 1.  If R is false, fail at compile-time, preferably
  179    with a diagnostic that includes the string-literal DIAGNOSTIC.  */
  180 
  181 #define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \
  182    (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))
  183 
  184 #ifdef __cplusplus
  185 # if !GNULIB_defined_struct__gl_verify_type
  186 template <int w>
  187   struct _gl_verify_type {
  188     unsigned int _gl_verify_error_if_negative: w;
  189   };
  190 #  define GNULIB_defined_struct__gl_verify_type 1
  191 # endif
  192 # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
  193     _gl_verify_type<(R) ? 1 : -1>
  194 #elif defined _GL_HAVE__STATIC_ASSERT
  195 # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
  196     struct {                                   \
  197       _Static_assert (R, DIAGNOSTIC);          \
  198       int _gl_dummy;                          \
  199     }
  200 #else
  201 # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
  202     struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
  203 #endif
  204 
  205 /* Verify requirement R at compile-time, as a declaration without a
  206    trailing ';'.  If R is false, fail at compile-time.
  207 
  208    This macro requires three or more arguments but uses at most the first
  209    two, so that the _Static_assert macro optionally defined below supports
  210    both the C11 two-argument syntax and the C2X one-argument syntax.
  211 
  212    Unfortunately, unlike C11, this implementation must appear as an
  213    ordinary declaration, and cannot appear inside struct { ... }.  */
  214 
  215 #if defined _GL_HAVE__STATIC_ASSERT
  216 # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC)
  217 #else
  218 # define _GL_VERIFY(R, DIAGNOSTIC, ...)                                \
  219     extern int (*_GL_GENSYM (_gl_verify_function) (void))          \
  220       [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
  221 #endif
  222 
  223 /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h.  */
  224 #ifdef _GL_STATIC_ASSERT_H
  225 # if !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert
  226 #  define _Static_assert(...) \
  227      _GL_VERIFY (__VA_ARGS__, "static assertion failed", -)
  228 # endif
  229 # if !defined _GL_HAVE_STATIC_ASSERT1 && !defined static_assert
  230 #  define static_assert _Static_assert /* C11 requires this #define.  */
  231 # endif
  232 #endif
  233 
  234 /* @assert.h omit start@  */
  235 
  236 /* Each of these macros verifies that its argument R is nonzero.  To
  237    be portable, R should be an integer constant expression.  Unlike
  238    assert (R), there is no run-time overhead.
  239 
  240    There are two macros, since no single macro can be used in all
  241    contexts in C.  verify_expr (R, E) is for scalar contexts, including
  242    integer constant expression contexts.  verify (R) is for declaration
  243    contexts, e.g., the top level.  */
  244 
  245 /* Verify requirement R at compile-time.  Return the value of the
  246    expression E.  */
  247 
  248 #define verify_expr(R, E) \
  249    (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E))
  250 
  251 /* Verify requirement R at compile-time, as a declaration without a
  252    trailing ';'.  verify (R) acts like static_assert (R) except that
  253    it is portable to C11/C++14 and earlier, it can issue better
  254    diagnostics, and its name is shorter and may be more convenient.  */
  255 
  256 #ifdef __PGI
  257 /* PGI barfs if R is long.  */
  258 # define verify(R) _GL_VERIFY (R, "verify (...)", -)
  259 #else
  260 # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -)
  261 #endif
  262 
  263 #ifndef __has_builtin
  264 # define __has_builtin(x) 0
  265 #endif
  266 
  267 /* Assume that R always holds.  Behavior is undefined if R is false,
  268    fails to evaluate, or has side effects.  Although assuming R can
  269    help a compiler generate better code or diagnostics, performance
  270    can suffer if R uses hard-to-optimize features such as function
  271    calls not inlined by the compiler.  */
  272 
  273 #if (__has_builtin (__builtin_unreachable) \
  274      || 4 < __GNUC__ + (5 <= __GNUC_MINOR__))
  275 # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
  276 #elif 1200 <= _MSC_VER
  277 # define assume(R) __assume (R)
  278 #elif ((defined GCC_LINT || defined lint) \
  279        && (__has_builtin (__builtin_trap) \
  280            || 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))))
  281   /* Doing it this way helps various packages when configured with
  282      --enable-gcc-warnings, which compiles with -Dlint.  It's nicer
  283      when 'assume' silences warnings even with older GCCs.  */
  284 # define assume(R) ((R) ? (void) 0 : __builtin_trap ())
  285 #else
  286   /* Some tools grok NOTREACHED, e.g., Oracle Studio 12.6.  */
  287 # define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0)
  288 #endif
  289 
  290 /* @assert.h omit end@  */
  291 
  292 #endif