1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * This file and its contents are supplied under the terms of the
4 * Common Development and Distribution License ("CDDL"), version 1.0.
5 * You may only use this file in accordance with the terms of version
6 * 1.0 of the CDDL.
7 *
8 * A full copy of the text of the CDDL should have accompanied this
9 * source. A copy of the CDDL is also available via the Internet at
10 * https://opensource.org/license/CDDL-1.0.
11 */
12 /*
13 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
14 * Use is subject to license terms.
15 */
16
17 #include_next <assert.h>
18
19 #ifndef _LIBSPL_ASSERT_H
20 #define _LIBSPL_ASSERT_H
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <sys/types.h>
26
27 /* Workaround for non-Clang compilers */
28 #ifndef __has_feature
29 #define __has_feature(x) 0
30 #endif
31
32 /* We need to workaround libspl_set_assert_ok() that we have for zdb */
33 #if __has_feature(attribute_analyzer_noreturn) || defined(__COVERITY__)
34 #define NORETURN __attribute__((__noreturn__))
35 #else
36 #define NORETURN
37 #endif
38
39 /* Set to non-zero to avoid abort()ing on an assertion failure */
40 extern void libspl_set_assert_ok(boolean_t val);
41
42 /* printf version of libspl_assert */
43 extern void libspl_assertf(const char *file, const char *func, int line,
44 const char *format, ...) NORETURN __attribute__((format(printf, 4, 5)));
45
46 static inline int
libspl_assert(const char * buf,const char * file,const char * func,int line)47 libspl_assert(const char *buf, const char *file, const char *func, int line)
48 {
49 libspl_assertf(file, func, line, "%s", buf);
50 return (0);
51 }
52
53 #ifdef verify
54 #undef verify
55 #endif
56
57 #define PANIC(fmt, a...) \
58 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)
59
60 #define VERIFY(cond) \
61 (void) ((!(cond)) && \
62 libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
63
64 #define VERIFYF(cond, STR, ...) \
65 do { \
66 if (!(cond)) \
67 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
68 "%s " STR, #cond, \
69 __VA_ARGS__); \
70 } while (0)
71
72 #define verify(cond) \
73 (void) ((!(cond)) && \
74 libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))
75
76 #define VERIFY3B(LEFT, OP, RIGHT) \
77 do { \
78 const boolean_t __left = (boolean_t)!!(LEFT); \
79 const boolean_t __right = (boolean_t)!!(RIGHT); \
80 if (!(__left OP __right)) \
81 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
82 "VERIFY3B(%s, %s, %s) failed " \
83 "(%d %s %d)", #LEFT, #OP, #RIGHT, \
84 __left, #OP, __right); \
85 } while (0)
86
87 #define VERIFY3S(LEFT, OP, RIGHT) \
88 do { \
89 const int64_t __left = (int64_t)(LEFT); \
90 const int64_t __right = (int64_t)(RIGHT); \
91 if (!(__left OP __right)) \
92 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
93 "VERIFY3S(%s, %s, %s) failed " \
94 "(%lld %s 0x%lld)", #LEFT, #OP, #RIGHT, \
95 (longlong_t)__left, #OP, (longlong_t)__right); \
96 } while (0)
97
98 #define VERIFY3U(LEFT, OP, RIGHT) \
99 do { \
100 const uint64_t __left = (uint64_t)(LEFT); \
101 const uint64_t __right = (uint64_t)(RIGHT); \
102 if (!(__left OP __right)) \
103 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
104 "VERIFY3U(%s, %s, %s) failed " \
105 "(%llu %s %llu)", #LEFT, #OP, #RIGHT, \
106 (u_longlong_t)__left, #OP, (u_longlong_t)__right); \
107 } while (0)
108
109 #define VERIFY3P(LEFT, OP, RIGHT) \
110 do { \
111 const uintptr_t __left = (uintptr_t)(LEFT); \
112 const uintptr_t __right = (uintptr_t)(RIGHT); \
113 if (!(__left OP __right)) \
114 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
115 "VERIFY3P(%s, %s, %s) failed " \
116 "(%p %s %p)", #LEFT, #OP, #RIGHT, \
117 (void *)__left, #OP, (void *)__right); \
118 } while (0)
119
120 #define VERIFY0(LEFT) \
121 do { \
122 const uint64_t __left = (uint64_t)(LEFT); \
123 if (!(__left == 0)) \
124 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
125 "VERIFY0(%s) failed (%lld)", #LEFT, \
126 (u_longlong_t)__left); \
127 } while (0)
128
129 #define VERIFY0P(LEFT) \
130 do { \
131 const uintptr_t __left = (uintptr_t)(LEFT); \
132 if (!(__left == 0)) \
133 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
134 "VERIFY0P(%s) failed (%p)", #LEFT, \
135 (void *)__left); \
136 } while (0)
137
138 /*
139 * This is just here because cstyle gets upset about #LEFT
140 * on a newline.
141 */
142
143 /* BEGIN CSTYLED */
144 #define VERIFY3BF(LEFT, OP, RIGHT, STR, ...) \
145 do { \
146 const boolean_t __left = (boolean_t)!!(LEFT); \
147 const boolean_t __right = (boolean_t)!!(RIGHT); \
148 if (!(__left OP __right)) \
149 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
150 "VERIFY3B(%s, %s, %s) failed " \
151 "(%d %s %d) " STR, #LEFT, #OP, #RIGHT, \
152 __left, #OP, __right, \
153 __VA_ARGS__); \
154 } while (0)
155
156 #define VERIFY3SF(LEFT, OP, RIGHT, STR, ...) \
157 do { \
158 const int64_t __left = (int64_t)(LEFT); \
159 const int64_t __right = (int64_t)(RIGHT); \
160 if (!(__left OP __right)) \
161 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
162 "VERIFY3S(%s, %s, %s) failed " \
163 "(%lld %s %lld) " STR, #LEFT, #OP, #RIGHT, \
164 (longlong_t)__left, #OP, (longlong_t)__right, \
165 __VA_ARGS__); \
166 } while (0)
167
168 #define VERIFY3UF(LEFT, OP, RIGHT, STR, ...) \
169 do { \
170 const uint64_t __left = (uint64_t)(LEFT); \
171 const uint64_t __right = (uint64_t)(RIGHT); \
172 if (!(__left OP __right)) \
173 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
174 "VERIFY3U(%s, %s, %s) failed " \
175 "(%llu %s %llu) " STR, #LEFT, #OP, #RIGHT, \
176 (u_longlong_t)__left, #OP, (u_longlong_t)__right, \
177 __VA_ARGS__); \
178 } while (0)
179
180 #define VERIFY3PF(LEFT, OP, RIGHT, STR, ...) \
181 do { \
182 const uintptr_t __left = (uintptr_t)(LEFT); \
183 const uintptr_t __right = (uintptr_t)(RIGHT); \
184 if (!(__left OP __right)) \
185 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
186 "VERIFY3P(%s, %s, %s) failed " \
187 "(%p %s %p) " STR, #LEFT, #OP, #RIGHT, \
188 (void *)__left, #OP, (void *)__right, \
189 __VA_ARGS__); \
190 } while (0)
191 /* END CSTYLED */
192
193 #define VERIFY0F(LEFT, STR, ...) \
194 do { \
195 const int64_t __left = (int64_t)(LEFT); \
196 if (!(__left == 0)) \
197 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
198 "VERIFY0(%s) failed (%lld) " STR, #LEFT, \
199 (longlong_t)__left, __VA_ARGS__); \
200 } while (0)
201
202 #define VERIFY0PF(LEFT, STR, ...) \
203 do { \
204 const uintptr_t __left = (uintptr_t)(LEFT); \
205 if (!(__left == 0)) \
206 libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \
207 "VERIFY0P(%s) failed (%p) " STR, #LEFT, \
208 (void *)__left, __VA_ARGS__); \
209 } while (0)
210
211 #define VERIFY_IMPLY(A, B) \
212 ((void)(((!(A)) || (B)) || \
213 libspl_assert("(" #A ") implies (" #B ")", \
214 __FILE__, __FUNCTION__, __LINE__)))
215
216 #define VERIFY_EQUIV(A, B) VERIFY3B(A, ==, B)
217
218 #ifdef assert
219 #undef assert
220 #endif
221
222 #ifdef NDEBUG
223 #define ASSERT3B(x, y, z) \
224 ((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
225 #define ASSERT3S(x, y, z) \
226 ((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
227 #define ASSERT3U(x, y, z) \
228 ((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
229 #define ASSERT3P(x, y, z) \
230 ((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))
231 #define ASSERT0(x) ((void) sizeof ((uintptr_t)(x)))
232 #define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))
233 #define ASSERT3BF(x, y, z, str, ...) ASSERT3B(x, y, z)
234 #define ASSERT3SF(x, y, z, str, ...) ASSERT3S(x, y, z)
235 #define ASSERT3UF(x, y, z, str, ...) ASSERT3U(x, y, z)
236 #define ASSERT3PF(x, y, z, str, ...) ASSERT3P(x, y, z)
237 #define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))
238 #define ASSERT0PF(x, str, ...) ASSERT0P(x)
239 #define ASSERT0F(x, str, ...) ASSERT0(x)
240 #define ASSERT(x) ((void) sizeof ((uintptr_t)(x)))
241 #define ASSERTF(x, str, ...) ASSERT(x)
242 #define assert(x) ((void) sizeof ((uintptr_t)(x)))
243 #define IMPLY(A, B) \
244 ((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
245 #define EQUIV(A, B) \
246 ((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))
247 #else
248 #define ASSERT3B VERIFY3B
249 #define ASSERT3S VERIFY3S
250 #define ASSERT3U VERIFY3U
251 #define ASSERT3P VERIFY3P
252 #define ASSERT0 VERIFY0
253 #define ASSERT0P VERIFY0P
254 #define ASSERT3BF VERIFY3BF
255 #define ASSERT3SF VERIFY3SF
256 #define ASSERT3UF VERIFY3UF
257 #define ASSERT3PF VERIFY3PF
258 #define ASSERT0PF VERIFY0PF
259 #define ASSERT0F VERIFY0F
260 #define ASSERT VERIFY
261 #define ASSERTF VERIFYF
262 #define assert VERIFY
263 #define IMPLY VERIFY_IMPLY
264 #define EQUIV VERIFY_EQUIV
265
266 #endif /* NDEBUG */
267
268 #endif /* _LIBSPL_ASSERT_H */
269