Blame src/gl/verify.h

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