Blame glib/gnulib/verify.h

Packit ae235b
/* Compile-time assert-like macros.
Packit ae235b
Packit ae235b
   Copyright (C) 2005-2006, 2009-2016 Free Software Foundation, Inc.
Packit ae235b
Packit ae235b
   This program is free software: you can redistribute it and/or modify
Packit ae235b
   it under the terms of the GNU Lesser General Public License as published by
Packit ae235b
   the Free Software Foundation; either version 2.1 of the License, or
Packit ae235b
   (at your option) any later version.
Packit ae235b
Packit ae235b
   This program is distributed in the hope that it will be useful,
Packit ae235b
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit ae235b
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit ae235b
   GNU Lesser General Public License for more details.
Packit ae235b
Packit ae235b
   You should have received a copy of the GNU Lesser General Public License
Packit ae235b
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit ae235b
Packit ae235b
/* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */
Packit ae235b
Packit ae235b
#ifndef _GL_VERIFY_H
Packit ae235b
#define _GL_VERIFY_H
Packit ae235b
Packit ae235b
Packit ae235b
/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11.
Packit ae235b
   This is supported by GCC 4.6.0 and later, in C mode, and its use
Packit ae235b
   here generates easier-to-read diagnostics when verify (R) fails.
Packit ae235b
Packit ae235b
   Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11.
Packit ae235b
   This will likely be supported by future GCC versions, in C++ mode.
Packit ae235b
Packit ae235b
   Use this only with GCC.  If we were willing to slow 'configure'
Packit ae235b
   down we could also use it with other compilers, but since this
Packit ae235b
   affects only the quality of diagnostics, why bother?  */
Packit ae235b
#if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \
Packit ae235b
     && (201112L <= __STDC_VERSION__  || !defined __STRICT_ANSI__) \
Packit ae235b
     && !defined __cplusplus)
Packit ae235b
# define _GL_HAVE__STATIC_ASSERT 1
Packit ae235b
#endif
Packit ae235b
/* The condition (99 < __GNUC__) is temporary, until we know about the
Packit ae235b
   first G++ release that supports static_assert.  */
Packit ae235b
#if (99 < __GNUC__) && defined __cplusplus
Packit ae235b
# define _GL_HAVE_STATIC_ASSERT 1
Packit ae235b
#endif
Packit ae235b
Packit ae235b
/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
Packit ae235b
   system headers, defines a conflicting _Static_assert that is no
Packit ae235b
   better than ours; override it.  */
Packit ae235b
#ifndef _GL_HAVE_STATIC_ASSERT
Packit ae235b
# include <stddef.h>
Packit ae235b
# undef _Static_assert
Packit ae235b
#endif
Packit ae235b
Packit ae235b
/* Each of these macros verifies that its argument R is nonzero.  To
Packit ae235b
   be portable, R should be an integer constant expression.  Unlike
Packit ae235b
   assert (R), there is no run-time overhead.
Packit ae235b
Packit ae235b
   If _Static_assert works, verify (R) uses it directly.  Similarly,
Packit ae235b
   _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct
Packit ae235b
   that is an operand of sizeof.
Packit ae235b
Packit ae235b
   The code below uses several ideas for C++ compilers, and for C
Packit ae235b
   compilers that do not support _Static_assert:
Packit ae235b
Packit ae235b
   * The first step is ((R) ? 1 : -1).  Given an expression R, of
Packit ae235b
     integral or boolean or floating-point type, this yields an
Packit ae235b
     expression of integral type, whose value is later verified to be
Packit ae235b
     constant and nonnegative.
Packit ae235b
Packit ae235b
   * Next this expression W is wrapped in a type
Packit ae235b
     struct _gl_verify_type {
Packit ae235b
       unsigned int _gl_verify_error_if_negative: W;
Packit ae235b
     }.
Packit ae235b
     If W is negative, this yields a compile-time error.  No compiler can
Packit ae235b
     deal with a bit-field of negative size.
Packit ae235b
Packit ae235b
     One might think that an array size check would have the same
Packit ae235b
     effect, that is, that the type struct { unsigned int dummy[W]; }
Packit ae235b
     would work as well.  However, inside a function, some compilers
Packit ae235b
     (such as C++ compilers and GNU C) allow local parameters and
Packit ae235b
     variables inside array size expressions.  With these compilers,
Packit ae235b
     an array size check would not properly diagnose this misuse of
Packit ae235b
     the verify macro:
Packit ae235b
Packit ae235b
       void function (int n) { verify (n < 0); }
Packit ae235b
Packit ae235b
   * For the verify macro, the struct _gl_verify_type will need to
Packit ae235b
     somehow be embedded into a declaration.  To be portable, this
Packit ae235b
     declaration must declare an object, a constant, a function, or a
Packit ae235b
     typedef name.  If the declared entity uses the type directly,
Packit ae235b
     such as in
Packit ae235b
Packit ae235b
       struct dummy {...};
Packit ae235b
       typedef struct {...} dummy;
Packit ae235b
       extern struct {...} *dummy;
Packit ae235b
       extern void dummy (struct {...} *);
Packit ae235b
       extern struct {...} *dummy (void);
Packit ae235b
Packit ae235b
     two uses of the verify macro would yield colliding declarations
Packit ae235b
     if the entity names are not disambiguated.  A workaround is to
Packit ae235b
     attach the current line number to the entity name:
Packit ae235b
Packit ae235b
       #define _GL_CONCAT0(x, y) x##y
Packit ae235b
       #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
Packit ae235b
       extern struct {...} * _GL_CONCAT (dummy, __LINE__);
Packit ae235b
Packit ae235b
     But this has the problem that two invocations of verify from
Packit ae235b
     within the same macro would collide, since the __LINE__ value
Packit ae235b
     would be the same for both invocations.  (The GCC __COUNTER__
Packit ae235b
     macro solves this problem, but is not portable.)
Packit ae235b
Packit ae235b
     A solution is to use the sizeof operator.  It yields a number,
Packit ae235b
     getting rid of the identity of the type.  Declarations like
Packit ae235b
Packit ae235b
       extern int dummy [sizeof (struct {...})];
Packit ae235b
       extern void dummy (int [sizeof (struct {...})]);
Packit ae235b
       extern int (*dummy (void)) [sizeof (struct {...})];
Packit ae235b
Packit ae235b
     can be repeated.
Packit ae235b
Packit ae235b
   * Should the implementation use a named struct or an unnamed struct?
Packit ae235b
     Which of the following alternatives can be used?
Packit ae235b
Packit ae235b
       extern int dummy [sizeof (struct {...})];
Packit ae235b
       extern int dummy [sizeof (struct _gl_verify_type {...})];
Packit ae235b
       extern void dummy (int [sizeof (struct {...})]);
Packit ae235b
       extern void dummy (int [sizeof (struct _gl_verify_type {...})]);
Packit ae235b
       extern int (*dummy (void)) [sizeof (struct {...})];
Packit ae235b
       extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];
Packit ae235b
Packit ae235b
     In the second and sixth case, the struct type is exported to the
Packit ae235b
     outer scope; two such declarations therefore collide.  GCC warns
Packit ae235b
     about the first, third, and fourth cases.  So the only remaining
Packit ae235b
     possibility is the fifth case:
Packit ae235b
Packit ae235b
       extern int (*dummy (void)) [sizeof (struct {...})];
Packit ae235b
Packit ae235b
   * GCC warns about duplicate declarations of the dummy function if
Packit ae235b
     -Wredundant-decls is used.  GCC 4.3 and later have a builtin
Packit ae235b
     __COUNTER__ macro that can let us generate unique identifiers for
Packit ae235b
     each dummy function, to suppress this warning.
Packit ae235b
Packit ae235b
   * This implementation exploits the fact that older versions of GCC,
Packit ae235b
     which do not support _Static_assert, also do not warn about the
Packit ae235b
     last declaration mentioned above.
Packit ae235b
Packit ae235b
   * GCC warns if -Wnested-externs is enabled and verify() is used
Packit ae235b
     within a function body; but inside a function, you can always
Packit ae235b
     arrange to use verify_expr() instead.
Packit ae235b
Packit ae235b
   * In C++, any struct definition inside sizeof is invalid.
Packit ae235b
     Use a template type to work around the problem.  */
Packit ae235b
Packit ae235b
/* Concatenate two preprocessor tokens.  */
Packit ae235b
#define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
Packit ae235b
#define _GL_CONCAT0(x, y) x##y
Packit ae235b
Packit ae235b
/* _GL_COUNTER is an integer, preferably one that changes each time we
Packit ae235b
   use it.  Use __COUNTER__ if it works, falling back on __LINE__
Packit ae235b
   otherwise.  __LINE__ isn't perfect, but it's better than a
Packit ae235b
   constant.  */
Packit ae235b
#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
Packit ae235b
# define _GL_COUNTER __COUNTER__
Packit ae235b
#else
Packit ae235b
# define _GL_COUNTER __LINE__
Packit ae235b
#endif
Packit ae235b
Packit ae235b
/* Generate a symbol with the given prefix, making it unique if
Packit ae235b
   possible.  */
Packit ae235b
#define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
Packit ae235b
Packit ae235b
/* Verify requirement R at compile-time, as an integer constant expression
Packit ae235b
   that returns 1.  If R is false, fail at compile-time, preferably
Packit ae235b
   with a diagnostic that includes the string-literal DIAGNOSTIC.  */
Packit ae235b
Packit ae235b
#define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \
Packit ae235b
   (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))
Packit ae235b
Packit ae235b
#ifdef __cplusplus
Packit ae235b
# if !GNULIB_defined_struct__gl_verify_type
Packit ae235b
template <int w>
Packit ae235b
  struct _gl_verify_type {
Packit ae235b
    unsigned int _gl_verify_error_if_negative: w;
Packit ae235b
  };
Packit ae235b
#  define GNULIB_defined_struct__gl_verify_type 1
Packit ae235b
# endif
Packit ae235b
# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
Packit ae235b
    _gl_verify_type<(R) ? 1 : -1>
Packit ae235b
#elif defined _GL_HAVE__STATIC_ASSERT
Packit ae235b
# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
Packit ae235b
    struct {                                   \
Packit ae235b
      _Static_assert (R, DIAGNOSTIC);          \
Packit ae235b
      int _gl_dummy;                          \
Packit ae235b
    }
Packit ae235b
#else
Packit ae235b
# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
Packit ae235b
    struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
Packit ae235b
#endif
Packit ae235b
Packit ae235b
/* Verify requirement R at compile-time, as a declaration without a
Packit ae235b
   trailing ';'.  If R is false, fail at compile-time, preferably
Packit ae235b
   with a diagnostic that includes the string-literal DIAGNOSTIC.
Packit ae235b
Packit ae235b
   Unfortunately, unlike C11, this implementation must appear as an
Packit ae235b
   ordinary declaration, and cannot appear inside struct { ... }.  */
Packit ae235b
Packit ae235b
#ifdef _GL_HAVE__STATIC_ASSERT
Packit ae235b
# define _GL_VERIFY _Static_assert
Packit ae235b
#else
Packit ae235b
# define _GL_VERIFY(R, DIAGNOSTIC)				       \
Packit ae235b
    extern int (*_GL_GENSYM (_gl_verify_function) (void))	       \
Packit ae235b
      [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
Packit ae235b
#endif
Packit ae235b
Packit ae235b
/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h.  */
Packit ae235b
#ifdef _GL_STATIC_ASSERT_H
Packit ae235b
# if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert
Packit ae235b
#  define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC)
Packit ae235b
# endif
Packit ae235b
# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert
Packit ae235b
#  define static_assert _Static_assert /* C11 requires this #define.  */
Packit ae235b
# endif
Packit ae235b
#endif
Packit ae235b
Packit ae235b
/* @assert.h omit start@  */
Packit ae235b
Packit ae235b
/* Each of these macros verifies that its argument R is nonzero.  To
Packit ae235b
   be portable, R should be an integer constant expression.  Unlike
Packit ae235b
   assert (R), there is no run-time overhead.
Packit ae235b
Packit ae235b
   There are two macros, since no single macro can be used in all
Packit ae235b
   contexts in C.  verify_true (R) is for scalar contexts, including
Packit ae235b
   integer constant expression contexts.  verify (R) is for declaration
Packit ae235b
   contexts, e.g., the top level.  */
Packit ae235b
Packit ae235b
/* Verify requirement R at compile-time, as an integer constant expression.
Packit ae235b
   Return 1.  This is equivalent to verify_expr (R, 1).
Packit ae235b
Packit ae235b
   verify_true is obsolescent; please use verify_expr instead.  */
Packit ae235b
Packit ae235b
#define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")")
Packit ae235b
Packit ae235b
/* Verify requirement R at compile-time.  Return the value of the
Packit ae235b
   expression E.  */
Packit ae235b
Packit ae235b
#define verify_expr(R, E) \
Packit ae235b
   (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E))
Packit ae235b
Packit ae235b
/* Verify requirement R at compile-time, as a declaration without a
Packit ae235b
   trailing ';'.  */
Packit ae235b
Packit ae235b
#define verify(R) _GL_VERIFY (R, "verify (" #R ")")
Packit ae235b
Packit ae235b
#ifndef __has_builtin
Packit ae235b
# define __has_builtin(x) 0
Packit ae235b
#endif
Packit ae235b
Packit ae235b
/* Assume that R always holds.  This lets the compiler optimize
Packit ae235b
   accordingly.  R should not have side-effects; it may or may not be
Packit ae235b
   evaluated.  Behavior is undefined if R is false.  */
Packit ae235b
Packit ae235b
#if (__has_builtin (__builtin_unreachable) \
Packit ae235b
     || 4 < __GNUC__ + (5 <= __GNUC_MINOR__))
Packit ae235b
# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
Packit ae235b
#elif 1200 <= _MSC_VER
Packit ae235b
# define assume(R) __assume (R)
Packit ae235b
#elif (defined lint \
Packit ae235b
       && (__has_builtin (__builtin_trap) \
Packit ae235b
           || 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))))
Packit ae235b
  /* Doing it this way helps various packages when configured with
Packit ae235b
     --enable-gcc-warnings, which compiles with -Dlint.  It's nicer
Packit ae235b
     when 'assume' silences warnings even with older GCCs.  */
Packit ae235b
# define assume(R) ((R) ? (void) 0 : __builtin_trap ())
Packit ae235b
#else
Packit ae235b
# define assume(R) ((void) (0 && (R)))
Packit ae235b
#endif
Packit ae235b
Packit ae235b
/* @assert.h omit end@  */
Packit ae235b
Packit ae235b
#endif