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