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