Ruby  3.1.4p223 (2023-03-30 revision HEAD)
assert.h
Go to the documentation of this file.
1 #ifndef RUBY_ASSERT_H /*-*-C++-*-vi:se ft=cpp:*/
2 #define RUBY_ASSERT_H
23 #include "ruby/internal/assume.h"
26 #include "ruby/internal/cast.h"
28 #include "ruby/backward/2/assume.h"
29 
30 /* RUBY_NDEBUG is very simple: after everything described below are done,
31  * define it with either NDEBUG is undefined (=0) or defined (=1). It is truly
32  * subordinate.
33  *
34  * RUBY_DEBUG versus NDEBUG is complicated. Assertions shall be:
35  *
36  * | -UNDEBUG | -DNDEBUG
37  * ---------------+----------+---------
38  * -URUBY_DEBUG | (*1) | disabled
39  * -DRUBY_DEBUG=0 | disabled | disabled
40  * -DRUBY_DEBUG=1 | enabled | (*2)
41  * -DRUBY_DEBUG | enabled | (*2)
42  *
43  * where:
44  *
45  * - (*1): Assertions shall be silently disabled, no warnings, in favour of
46  * commit 21991e6ca59274e41a472b5256bd3245f6596c90.
47  *
48  * - (*2): Compile-time warnings shall be issued.
49  */
50 
53 /*
54  * Pro tip: `!!RUBY_DEBUG-1` expands to...
55  *
56  * - `!!(-1)` (== `!0` == `1`) when RUBY_DEBUG is defined to be empty,
57  * - `(!!0)-1` (== `0-1` == `-1`) when RUBY_DEBUG is defined as 0, and
58  * - `(!!n)-1` (== `1-1` == `0`) when RUBY_DEBUG is defined as something else.
59  */
60 #if ! defined(RUBY_DEBUG)
61 # define RBIMPL_RUBY_DEBUG 0
62 #elif !!RUBY_DEBUG-1 < 0
63 # define RBIMPL_RUBY_DEBUG 0
64 #else
65 # define RBIMPL_RUBY_DEBUG 1
66 #endif
67 
68 /*
69  * ISO/IEC 9899 (all past versions) says that "If NDEBUG is defined as a macro
70  * name at the point in the source file where <assert.h> is included, ..."
71  * which means we must not take its defined value into account.
72  */
73 #if defined(NDEBUG)
74 # define RBIMPL_NDEBUG 1
75 #else
76 # define RBIMPL_NDEBUG 0
77 #endif
78 
81 /* Here we go... */
82 #undef RUBY_DEBUG
83 #undef RUBY_NDEBUG
84 #undef NDEBUG
85 #if defined(__DOXYGEN__)
86 #
87 # define RUBY_DEBUG 0
88 #
89 # define NDEBUG
90 #
91 # define RUBY_NDEBUG 1
92 
93 #elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 0)
94 # /* Assertions disabled as per request, no conflicts. */
95 # define RUBY_DEBUG 0
96 # define RUBY_NDEBUG 1
97 # define NDEBUG
98 
99 #elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 1)
100 # /* Assertions enabled as per request, no conflicts. */
101 # define RUBY_DEBUG 1
102 # define RUBY_NDEBUG 0
103 # /* keep NDEBUG undefined */
104 
105 #elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 0)
106 # /* The (*1) situation in avobe diagram. */
107 # define RUBY_DEBUG 0
108 # define RUBY_NDEBUG 1
109 # define NDEBUG
110 
111 #elif (RBIMPL_NDEBUG == 1) && (RBIMPL_RUBY_DEBUG == 1)
112 # /* The (*2) situation in above diagram. */
113 # define RUBY_DEBUG 1
114 # define RUBY_NDEBUG 0
115 # /* keep NDEBUG undefined */
116 
117 # if defined(_MSC_VER)
118 # pragma message("NDEBUG is ignored because RUBY_DEBUG>0.")
119 # elif defined(__GNUC__)
120 # pragma GCC warning "NDEBUG is ignored because RUBY_DEBUG>0."
121 # else
122 # error NDEBUG is ignored because RUBY_DEBUG>0.
123 # endif
124 #endif
125 #undef RBIMPL_NDEBUG
126 #undef RBIMPL_RUBY_DEBUG
127 
129 #define RBIMPL_ASSERT_NOTHING RBIMPL_CAST((void)0)
130 
134 void rb_assert_failure(const char *file, int line, const char *name, const char *expr);
136 
137 #ifdef RUBY_FUNCTION_NAME_STRING
138 # define RBIMPL_ASSERT_FUNC RUBY_FUNCTION_NAME_STRING
139 #else
140 # define RBIMPL_ASSERT_FUNC RBIMPL_CAST((const char *)0)
141 #endif
142 
150 #define RUBY_ASSERT_FAIL(mesg) \
151  rb_assert_failure(__FILE__, __LINE__, RBIMPL_ASSERT_FUNC, mesg)
152 
159 #define RUBY_ASSERT_MESG(expr, mesg) \
160  (RB_LIKELY(expr) ? RBIMPL_ASSERT_NOTHING : RUBY_ASSERT_FAIL(mesg))
161 
167 #define RUBY_ASSERT_ALWAYS(expr) RUBY_ASSERT_MESG((expr), #expr)
168 
174 #if RUBY_DEBUG
175 # define RUBY_ASSERT(expr) RUBY_ASSERT_MESG((expr), #expr)
176 #else
177 # define RUBY_ASSERT(expr) RBIMPL_ASSERT_NOTHING
178 #endif
179 
187 /* Currently `RUBY_DEBUG == ! defined(NDEBUG)` is always true. There is no
188  * difference any longer between this one and `RUBY_ASSERT`. */
189 #if defined(NDEBUG)
190 # define RUBY_ASSERT_NDEBUG(expr) RBIMPL_ASSERT_NOTHING
191 #else
192 # define RUBY_ASSERT_NDEBUG(expr) RUBY_ASSERT_MESG((expr), #expr)
193 #endif
194 
199 #if RUBY_DEBUG
200 # define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) RUBY_ASSERT_MESG((expr), (mesg))
201 #else
202 # define RUBY_ASSERT_MESG_WHEN(cond, expr, mesg) \
203  ((cond) ? RUBY_ASSERT_MESG((expr), (mesg)) : RBIMPL_ASSERT_NOTHING)
204 #endif
205 
213 #define RUBY_ASSERT_WHEN(cond, expr) RUBY_ASSERT_MESG_WHEN((cond), (expr), #expr)
214 
220 #if RUBY_DEBUG
221 # define RBIMPL_ASSERT_OR_ASSUME(expr) RUBY_ASSERT_ALWAYS(expr)
222 #elif RBIMPL_COMPILER_BEFORE(Clang, 7, 0, 0)
223 # /* See commit 67d259c5dccd31fe49d417fec169977712ffdf10 */
224 # define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
225 #elif defined(RUBY_ASSERT_NOASSUME)
226 # /* See commit d300a734414ef6de7e8eb563b7cc4389c455ed08 */
227 # define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
228 #elif ! defined(RBIMPL_HAVE___ASSUME)
229 # define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSERT_NOTHING
230 #else
231 # define RBIMPL_ASSERT_OR_ASSUME(expr) RBIMPL_ASSUME(expr)
232 #endif
233 
234 #endif /* RUBY_ASSERT_H */
Defines ASSUME / RB_LIKELY / UNREACHABLE.
Defines RBIMPL_ATTR_COLD.
#define RBIMPL_ATTR_COLD()
Wraps (or simulates) __attribute__((cold))
Definition: cold.h:32
Tweaking visibility of C variables/functions.
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
Definition: dllexport.h:106
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
Definition: dllexport.h:97
RBIMPL_ATTR_NORETURN() void rb_eof_error(void)
Utility function to raise rb_eEOFError.
Defines RBIMPL_ASSUME / RBIMPL_UNREACHABLE.
Defines RBIMPL_ATTR_NORETURN.