File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libiconv / srclib / verify.h
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 13:38:46 2021 UTC (3 years, 3 months ago) by misho
Branches: libiconv, MAIN
CVS tags: v1_16p0, HEAD
libiconv 1.16

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>