xref: /dragonfly/contrib/grep/lib/verify.h (revision 09d4459f)
195b7b453SJohn Marino /* Compile-time assert-like macros.
295b7b453SJohn Marino 
3*09d4459fSDaniel Fojt    Copyright (C) 2005-2006, 2009-2020 Free Software Foundation, Inc.
495b7b453SJohn Marino 
595b7b453SJohn Marino    This program is free software: you can redistribute it and/or modify
695b7b453SJohn Marino    it under the terms of the GNU General Public License as published by
795b7b453SJohn Marino    the Free Software Foundation; either version 3 of the License, or
895b7b453SJohn Marino    (at your option) any later version.
995b7b453SJohn Marino 
1095b7b453SJohn Marino    This program is distributed in the hope that it will be useful,
1195b7b453SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
1295b7b453SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1395b7b453SJohn Marino    GNU General Public License for more details.
1495b7b453SJohn Marino 
1595b7b453SJohn Marino    You should have received a copy of the GNU General Public License
16*09d4459fSDaniel Fojt    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
1795b7b453SJohn Marino 
1895b7b453SJohn Marino /* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */
1995b7b453SJohn Marino 
20200fbe8dSJohn Marino #ifndef _GL_VERIFY_H
21200fbe8dSJohn Marino #define _GL_VERIFY_H
22200fbe8dSJohn Marino 
23200fbe8dSJohn Marino 
24*09d4459fSDaniel Fojt /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert (R, DIAGNOSTIC)
25*09d4459fSDaniel Fojt    works as per C11.  This is supported by GCC 4.6.0 and later, in C
26*09d4459fSDaniel Fojt    mode.
27200fbe8dSJohn Marino 
28*09d4459fSDaniel Fojt    Define _GL_HAVE__STATIC_ASSERT1 to 1 if _Static_assert (R) works as
29*09d4459fSDaniel Fojt    per C2X, and define _GL_HAVE_STATIC_ASSERT1 if static_assert (R)
30*09d4459fSDaniel Fojt    works as per C++17.  This is supported by GCC 9.1 and later.
31200fbe8dSJohn Marino 
32*09d4459fSDaniel Fojt    Support compilers claiming conformance to the relevant standard,
33*09d4459fSDaniel Fojt    and also support GCC when not pedantic.  If we were willing to slow
34*09d4459fSDaniel Fojt    'configure' down we could also use it with other compilers, but
35*09d4459fSDaniel Fojt    since this affects only the quality of diagnostics, why bother?  */
36*09d4459fSDaniel Fojt #ifndef __cplusplus
37*09d4459fSDaniel Fojt # if (201112L <= __STDC_VERSION__ \
38*09d4459fSDaniel Fojt       || (!defined __STRICT_ANSI__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__)))
39200fbe8dSJohn Marino #  define _GL_HAVE__STATIC_ASSERT 1
40200fbe8dSJohn Marino # endif
41*09d4459fSDaniel Fojt # if (202000L <= __STDC_VERSION__ \
42*09d4459fSDaniel Fojt       || (!defined __STRICT_ANSI__ && 9 <= __GNUC__))
43*09d4459fSDaniel Fojt #  define _GL_HAVE__STATIC_ASSERT1 1
44*09d4459fSDaniel Fojt # endif
45*09d4459fSDaniel Fojt #else
46*09d4459fSDaniel Fojt # if 201703L <= __cplusplus || 9 <= __GNUC__
47*09d4459fSDaniel Fojt #  define _GL_HAVE_STATIC_ASSERT1 1
48*09d4459fSDaniel Fojt # endif
49200fbe8dSJohn Marino #endif
5095b7b453SJohn Marino 
51680a9cb8SJohn Marino /* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
52680a9cb8SJohn Marino    system headers, defines a conflicting _Static_assert that is no
53680a9cb8SJohn Marino    better than ours; override it.  */
54*09d4459fSDaniel Fojt #ifndef _GL_HAVE__STATIC_ASSERT
55680a9cb8SJohn Marino # include <stddef.h>
56680a9cb8SJohn Marino # undef _Static_assert
57680a9cb8SJohn Marino #endif
58680a9cb8SJohn Marino 
5995b7b453SJohn Marino /* Each of these macros verifies that its argument R is nonzero.  To
6095b7b453SJohn Marino    be portable, R should be an integer constant expression.  Unlike
6195b7b453SJohn Marino    assert (R), there is no run-time overhead.
6295b7b453SJohn Marino 
63200fbe8dSJohn Marino    If _Static_assert works, verify (R) uses it directly.  Similarly,
64200fbe8dSJohn Marino    _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct
65200fbe8dSJohn Marino    that is an operand of sizeof.
6695b7b453SJohn Marino 
67200fbe8dSJohn Marino    The code below uses several ideas for C++ compilers, and for C
68200fbe8dSJohn Marino    compilers that do not support _Static_assert:
6995b7b453SJohn Marino 
7095b7b453SJohn Marino    * The first step is ((R) ? 1 : -1).  Given an expression R, of
7195b7b453SJohn Marino      integral or boolean or floating-point type, this yields an
7295b7b453SJohn Marino      expression of integral type, whose value is later verified to be
7395b7b453SJohn Marino      constant and nonnegative.
7495b7b453SJohn Marino 
7595b7b453SJohn Marino    * Next this expression W is wrapped in a type
76200fbe8dSJohn Marino      struct _gl_verify_type {
77200fbe8dSJohn Marino        unsigned int _gl_verify_error_if_negative: W;
78200fbe8dSJohn Marino      }.
7995b7b453SJohn Marino      If W is negative, this yields a compile-time error.  No compiler can
8095b7b453SJohn Marino      deal with a bit-field of negative size.
8195b7b453SJohn Marino 
8295b7b453SJohn Marino      One might think that an array size check would have the same
8395b7b453SJohn Marino      effect, that is, that the type struct { unsigned int dummy[W]; }
8495b7b453SJohn Marino      would work as well.  However, inside a function, some compilers
8595b7b453SJohn Marino      (such as C++ compilers and GNU C) allow local parameters and
8695b7b453SJohn Marino      variables inside array size expressions.  With these compilers,
8795b7b453SJohn Marino      an array size check would not properly diagnose this misuse of
8895b7b453SJohn Marino      the verify macro:
8995b7b453SJohn Marino 
9095b7b453SJohn Marino        void function (int n) { verify (n < 0); }
9195b7b453SJohn Marino 
92200fbe8dSJohn Marino    * For the verify macro, the struct _gl_verify_type will need to
9395b7b453SJohn Marino      somehow be embedded into a declaration.  To be portable, this
9495b7b453SJohn Marino      declaration must declare an object, a constant, a function, or a
9595b7b453SJohn Marino      typedef name.  If the declared entity uses the type directly,
9695b7b453SJohn Marino      such as in
9795b7b453SJohn Marino 
9895b7b453SJohn Marino        struct dummy {...};
9995b7b453SJohn Marino        typedef struct {...} dummy;
10095b7b453SJohn Marino        extern struct {...} *dummy;
10195b7b453SJohn Marino        extern void dummy (struct {...} *);
10295b7b453SJohn Marino        extern struct {...} *dummy (void);
10395b7b453SJohn Marino 
10495b7b453SJohn Marino      two uses of the verify macro would yield colliding declarations
10595b7b453SJohn Marino      if the entity names are not disambiguated.  A workaround is to
10695b7b453SJohn Marino      attach the current line number to the entity name:
10795b7b453SJohn Marino 
10895b7b453SJohn Marino        #define _GL_CONCAT0(x, y) x##y
10995b7b453SJohn Marino        #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
11095b7b453SJohn Marino        extern struct {...} * _GL_CONCAT (dummy, __LINE__);
11195b7b453SJohn Marino 
11295b7b453SJohn Marino      But this has the problem that two invocations of verify from
11395b7b453SJohn Marino      within the same macro would collide, since the __LINE__ value
11495b7b453SJohn Marino      would be the same for both invocations.  (The GCC __COUNTER__
11595b7b453SJohn Marino      macro solves this problem, but is not portable.)
11695b7b453SJohn Marino 
11795b7b453SJohn Marino      A solution is to use the sizeof operator.  It yields a number,
11895b7b453SJohn Marino      getting rid of the identity of the type.  Declarations like
11995b7b453SJohn Marino 
12095b7b453SJohn Marino        extern int dummy [sizeof (struct {...})];
12195b7b453SJohn Marino        extern void dummy (int [sizeof (struct {...})]);
12295b7b453SJohn Marino        extern int (*dummy (void)) [sizeof (struct {...})];
12395b7b453SJohn Marino 
12495b7b453SJohn Marino      can be repeated.
12595b7b453SJohn Marino 
12695b7b453SJohn Marino    * Should the implementation use a named struct or an unnamed struct?
12795b7b453SJohn Marino      Which of the following alternatives can be used?
12895b7b453SJohn Marino 
12995b7b453SJohn Marino        extern int dummy [sizeof (struct {...})];
130200fbe8dSJohn Marino        extern int dummy [sizeof (struct _gl_verify_type {...})];
13195b7b453SJohn Marino        extern void dummy (int [sizeof (struct {...})]);
132200fbe8dSJohn Marino        extern void dummy (int [sizeof (struct _gl_verify_type {...})]);
13395b7b453SJohn Marino        extern int (*dummy (void)) [sizeof (struct {...})];
134200fbe8dSJohn Marino        extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];
13595b7b453SJohn Marino 
13695b7b453SJohn Marino      In the second and sixth case, the struct type is exported to the
13795b7b453SJohn Marino      outer scope; two such declarations therefore collide.  GCC warns
13895b7b453SJohn Marino      about the first, third, and fourth cases.  So the only remaining
13995b7b453SJohn Marino      possibility is the fifth case:
14095b7b453SJohn Marino 
14195b7b453SJohn Marino        extern int (*dummy (void)) [sizeof (struct {...})];
14295b7b453SJohn Marino 
14395b7b453SJohn Marino    * GCC warns about duplicate declarations of the dummy function if
144a8597f6cSJohn Marino      -Wredundant-decls is used.  GCC 4.3 and later have a builtin
14595b7b453SJohn Marino      __COUNTER__ macro that can let us generate unique identifiers for
14695b7b453SJohn Marino      each dummy function, to suppress this warning.
14795b7b453SJohn Marino 
148200fbe8dSJohn Marino    * This implementation exploits the fact that older versions of GCC,
149200fbe8dSJohn Marino      which do not support _Static_assert, also do not warn about the
150200fbe8dSJohn Marino      last declaration mentioned above.
15195b7b453SJohn Marino 
152*09d4459fSDaniel Fojt    * GCC warns if -Wnested-externs is enabled and 'verify' is used
153a8597f6cSJohn Marino      within a function body; but inside a function, you can always
154*09d4459fSDaniel Fojt      arrange to use verify_expr instead.
155a8597f6cSJohn Marino 
15695b7b453SJohn Marino    * In C++, any struct definition inside sizeof is invalid.
15795b7b453SJohn Marino      Use a template type to work around the problem.  */
15895b7b453SJohn Marino 
15995b7b453SJohn Marino /* Concatenate two preprocessor tokens.  */
16095b7b453SJohn Marino #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
16195b7b453SJohn Marino #define _GL_CONCAT0(x, y) x##y
16295b7b453SJohn Marino 
16395b7b453SJohn Marino /* _GL_COUNTER is an integer, preferably one that changes each time we
16495b7b453SJohn Marino    use it.  Use __COUNTER__ if it works, falling back on __LINE__
16595b7b453SJohn Marino    otherwise.  __LINE__ isn't perfect, but it's better than a
16695b7b453SJohn Marino    constant.  */
16795b7b453SJohn Marino #if defined __COUNTER__ && __COUNTER__ != __COUNTER__
16895b7b453SJohn Marino # define _GL_COUNTER __COUNTER__
16995b7b453SJohn Marino #else
17095b7b453SJohn Marino # define _GL_COUNTER __LINE__
17195b7b453SJohn Marino #endif
17295b7b453SJohn Marino 
17395b7b453SJohn Marino /* Generate a symbol with the given prefix, making it unique if
17495b7b453SJohn Marino    possible.  */
17595b7b453SJohn Marino #define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
17695b7b453SJohn Marino 
177200fbe8dSJohn Marino /* Verify requirement R at compile-time, as an integer constant expression
178200fbe8dSJohn Marino    that returns 1.  If R is false, fail at compile-time, preferably
179200fbe8dSJohn Marino    with a diagnostic that includes the string-literal DIAGNOSTIC.  */
180200fbe8dSJohn Marino 
181200fbe8dSJohn Marino #define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \
182200fbe8dSJohn Marino    (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))
18395b7b453SJohn Marino 
18495b7b453SJohn Marino #ifdef __cplusplus
185200fbe8dSJohn Marino # if !GNULIB_defined_struct__gl_verify_type
18695b7b453SJohn Marino template <int w>
187200fbe8dSJohn Marino   struct _gl_verify_type {
188200fbe8dSJohn Marino     unsigned int _gl_verify_error_if_negative: w;
189200fbe8dSJohn Marino   };
190200fbe8dSJohn Marino #  define GNULIB_defined_struct__gl_verify_type 1
19195b7b453SJohn Marino # endif
192200fbe8dSJohn Marino # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
193200fbe8dSJohn Marino     _gl_verify_type<(R) ? 1 : -1>
194200fbe8dSJohn Marino #elif defined _GL_HAVE__STATIC_ASSERT
195200fbe8dSJohn Marino # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
196200fbe8dSJohn Marino     struct {                                   \
197200fbe8dSJohn Marino       _Static_assert (R, DIAGNOSTIC);          \
198200fbe8dSJohn Marino       int _gl_dummy;                          \
199200fbe8dSJohn Marino     }
200200fbe8dSJohn Marino #else
201200fbe8dSJohn Marino # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
202200fbe8dSJohn Marino     struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
203200fbe8dSJohn Marino #endif
204200fbe8dSJohn Marino 
205200fbe8dSJohn Marino /* Verify requirement R at compile-time, as a declaration without a
206*09d4459fSDaniel Fojt    trailing ';'.  If R is false, fail at compile-time.
207*09d4459fSDaniel Fojt 
208*09d4459fSDaniel Fojt    This macro requires three or more arguments but uses at most the first
209*09d4459fSDaniel Fojt    two, so that the _Static_assert macro optionally defined below supports
210*09d4459fSDaniel Fojt    both the C11 two-argument syntax and the C2X one-argument syntax.
211200fbe8dSJohn Marino 
212cf28ed85SJohn Marino    Unfortunately, unlike C11, this implementation must appear as an
213200fbe8dSJohn Marino    ordinary declaration, and cannot appear inside struct { ... }.  */
214200fbe8dSJohn Marino 
215*09d4459fSDaniel Fojt #if defined _GL_HAVE__STATIC_ASSERT
216*09d4459fSDaniel Fojt # define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC)
217200fbe8dSJohn Marino #else
218*09d4459fSDaniel Fojt # define _GL_VERIFY(R, DIAGNOSTIC, ...)                                \
219200fbe8dSJohn Marino     extern int (*_GL_GENSYM (_gl_verify_function) (void))	       \
220200fbe8dSJohn Marino       [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
221200fbe8dSJohn Marino #endif
222200fbe8dSJohn Marino 
223200fbe8dSJohn Marino /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h.  */
224200fbe8dSJohn Marino #ifdef _GL_STATIC_ASSERT_H
225*09d4459fSDaniel Fojt # if !defined _GL_HAVE__STATIC_ASSERT1 && !defined _Static_assert
226*09d4459fSDaniel Fojt #  define _Static_assert(...) \
227*09d4459fSDaniel Fojt      _GL_VERIFY (__VA_ARGS__, "static assertion failed", -)
228200fbe8dSJohn Marino # endif
229*09d4459fSDaniel Fojt # if !defined _GL_HAVE_STATIC_ASSERT1 && !defined static_assert
230cf28ed85SJohn Marino #  define static_assert _Static_assert /* C11 requires this #define.  */
231200fbe8dSJohn Marino # endif
232200fbe8dSJohn Marino #endif
233200fbe8dSJohn Marino 
234200fbe8dSJohn Marino /* @assert.h omit start@  */
235200fbe8dSJohn Marino 
236*09d4459fSDaniel Fojt #if 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))
237*09d4459fSDaniel Fojt # define _GL_HAS_BUILTIN_TRAP 1
238*09d4459fSDaniel Fojt #elif defined __has_builtin
239*09d4459fSDaniel Fojt # define _GL_HAS_BUILTIN_TRAP __has_builtin (__builtin_trap)
240*09d4459fSDaniel Fojt #else
241*09d4459fSDaniel Fojt # define _GL_HAS_BUILTIN_TRAP 0
242*09d4459fSDaniel Fojt #endif
243*09d4459fSDaniel Fojt 
244*09d4459fSDaniel Fojt #if 4 < __GNUC__ + (5 <= __GNUC_MINOR__)
245*09d4459fSDaniel Fojt # define _GL_HAS_BUILTIN_UNREACHABLE 1
246*09d4459fSDaniel Fojt #elif defined __has_builtin
247*09d4459fSDaniel Fojt # define _GL_HAS_BUILTIN_UNREACHABLE __has_builtin (__builtin_unreachable)
248*09d4459fSDaniel Fojt #else
249*09d4459fSDaniel Fojt # define _GL_HAS_BUILTIN_UNREACHABLE 0
250*09d4459fSDaniel Fojt #endif
251*09d4459fSDaniel Fojt 
252200fbe8dSJohn Marino /* Each of these macros verifies that its argument R is nonzero.  To
253200fbe8dSJohn Marino    be portable, R should be an integer constant expression.  Unlike
254200fbe8dSJohn Marino    assert (R), there is no run-time overhead.
255200fbe8dSJohn Marino 
256200fbe8dSJohn Marino    There are two macros, since no single macro can be used in all
257*09d4459fSDaniel Fojt    contexts in C.  verify_expr (R, E) is for scalar contexts, including
258200fbe8dSJohn Marino    integer constant expression contexts.  verify (R) is for declaration
259200fbe8dSJohn Marino    contexts, e.g., the top level.  */
260200fbe8dSJohn Marino 
261200fbe8dSJohn Marino /* Verify requirement R at compile-time.  Return the value of the
262200fbe8dSJohn Marino    expression E.  */
263200fbe8dSJohn Marino 
264200fbe8dSJohn Marino #define verify_expr(R, E) \
265200fbe8dSJohn Marino    (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E))
26695b7b453SJohn Marino 
26795b7b453SJohn Marino /* Verify requirement R at compile-time, as a declaration without a
268*09d4459fSDaniel Fojt    trailing ';'.  verify (R) acts like static_assert (R) except that
269*09d4459fSDaniel Fojt    it is portable to C11/C++14 and earlier, it can issue better
270*09d4459fSDaniel Fojt    diagnostics, and its name is shorter and may be more convenient.  */
27195b7b453SJohn Marino 
272*09d4459fSDaniel Fojt #ifdef __PGI
273*09d4459fSDaniel Fojt /* PGI barfs if R is long.  */
274*09d4459fSDaniel Fojt # define verify(R) _GL_VERIFY (R, "verify (...)", -)
275*09d4459fSDaniel Fojt #else
276*09d4459fSDaniel Fojt # define verify(R) _GL_VERIFY (R, "verify (" #R ")", -)
277680a9cb8SJohn Marino #endif
278680a9cb8SJohn Marino 
279*09d4459fSDaniel Fojt /* Assume that R always holds.  Behavior is undefined if R is false,
280*09d4459fSDaniel Fojt    fails to evaluate, or has side effects.  Although assuming R can
281*09d4459fSDaniel Fojt    help a compiler generate better code or diagnostics, performance
282*09d4459fSDaniel Fojt    can suffer if R uses hard-to-optimize features such as function
283*09d4459fSDaniel Fojt    calls not inlined by the compiler.  */
284680a9cb8SJohn Marino 
285*09d4459fSDaniel Fojt #if _GL_HAS_BUILTIN_UNREACHABLE
286680a9cb8SJohn Marino # define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
287680a9cb8SJohn Marino #elif 1200 <= _MSC_VER
288680a9cb8SJohn Marino # define assume(R) __assume (R)
289*09d4459fSDaniel Fojt #elif (defined GCC_LINT || defined lint) && _GL_HAS_BUILTIN_TRAP
290680a9cb8SJohn Marino   /* Doing it this way helps various packages when configured with
291680a9cb8SJohn Marino      --enable-gcc-warnings, which compiles with -Dlint.  It's nicer
292680a9cb8SJohn Marino      when 'assume' silences warnings even with older GCCs.  */
293680a9cb8SJohn Marino # define assume(R) ((R) ? (void) 0 : __builtin_trap ())
294680a9cb8SJohn Marino #else
295*09d4459fSDaniel Fojt   /* Some tools grok NOTREACHED, e.g., Oracle Studio 12.6.  */
296*09d4459fSDaniel Fojt # define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0)
297680a9cb8SJohn Marino #endif
298680a9cb8SJohn Marino 
299200fbe8dSJohn Marino /* @assert.h omit end@  */
30095b7b453SJohn Marino 
30195b7b453SJohn Marino #endif
302