Path: blob/main/sys/contrib/openzfs/lib/libspl/include/assert.h
48406 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* Common Development and Distribution License, Version 1.0 only6* (the "License"). You may not use this file except in compliance7* with the License.8*9* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE10* or https://opensource.org/licenses/CDDL-1.0.11* See the License for the specific language governing permissions12* and limitations under the License.13*14* When distributing Covered Code, include this CDDL HEADER in each15* file and include the License file at usr/src/OPENSOLARIS.LICENSE.16* If applicable, add the following below this CDDL HEADER, with the17* fields enclosed by brackets "[]" replaced with your own identifying18* information: Portions Copyright [yyyy] [name of copyright owner]19*20* CDDL HEADER END21*/22/*23* Copyright 2007 Sun Microsystems, Inc. All rights reserved.24* Use is subject to license terms.25*/2627#include_next <assert.h>2829#ifndef _LIBSPL_ASSERT_H30#define _LIBSPL_ASSERT_H3132#include <stdio.h>33#include <stdlib.h>34#include <stdarg.h>35#include <sys/types.h>3637/* Workaround for non-Clang compilers */38#ifndef __has_feature39#define __has_feature(x) 040#endif4142/* We need to workaround libspl_set_assert_ok() that we have for zdb */43#if __has_feature(attribute_analyzer_noreturn) || defined(__COVERITY__)44#define NORETURN __attribute__((__noreturn__))45#else46#define NORETURN47#endif4849/* Set to non-zero to avoid abort()ing on an assertion failure */50extern void libspl_set_assert_ok(boolean_t val);5152/* printf version of libspl_assert */53extern void libspl_assertf(const char *file, const char *func, int line,54const char *format, ...) NORETURN __attribute__((format(printf, 4, 5)));5556static inline int57libspl_assert(const char *buf, const char *file, const char *func, int line)58{59libspl_assertf(file, func, line, "%s", buf);60return (0);61}6263#ifdef verify64#undef verify65#endif6667#define PANIC(fmt, a...) \68libspl_assertf(__FILE__, __FUNCTION__, __LINE__, fmt, ## a)6970#define VERIFY(cond) \71(void) ((!(cond)) && \72libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))7374#define VERIFYF(cond, STR, ...) \75do { \76if (!(cond)) \77libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \78"%s " STR, #cond, \79__VA_ARGS__); \80} while (0)8182#define verify(cond) \83(void) ((!(cond)) && \84libspl_assert(#cond, __FILE__, __FUNCTION__, __LINE__))8586#define VERIFY3B(LEFT, OP, RIGHT) \87do { \88const boolean_t __left = (boolean_t)!!(LEFT); \89const boolean_t __right = (boolean_t)!!(RIGHT); \90if (!(__left OP __right)) \91libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \92"VERIFY3B(%s, %s, %s) failed " \93"(%d %s %d)", #LEFT, #OP, #RIGHT, \94__left, #OP, __right); \95} while (0)9697#define VERIFY3S(LEFT, OP, RIGHT) \98do { \99const int64_t __left = (int64_t)(LEFT); \100const int64_t __right = (int64_t)(RIGHT); \101if (!(__left OP __right)) \102libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \103"VERIFY3S(%s, %s, %s) failed " \104"(%lld %s 0x%lld)", #LEFT, #OP, #RIGHT, \105(longlong_t)__left, #OP, (longlong_t)__right); \106} while (0)107108#define VERIFY3U(LEFT, OP, RIGHT) \109do { \110const uint64_t __left = (uint64_t)(LEFT); \111const uint64_t __right = (uint64_t)(RIGHT); \112if (!(__left OP __right)) \113libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \114"VERIFY3U(%s, %s, %s) failed " \115"(%llu %s %llu)", #LEFT, #OP, #RIGHT, \116(u_longlong_t)__left, #OP, (u_longlong_t)__right); \117} while (0)118119#define VERIFY3P(LEFT, OP, RIGHT) \120do { \121const uintptr_t __left = (uintptr_t)(LEFT); \122const uintptr_t __right = (uintptr_t)(RIGHT); \123if (!(__left OP __right)) \124libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \125"VERIFY3P(%s, %s, %s) failed " \126"(%p %s %p)", #LEFT, #OP, #RIGHT, \127(void *)__left, #OP, (void *)__right); \128} while (0)129130#define VERIFY0(LEFT) \131do { \132const uint64_t __left = (uint64_t)(LEFT); \133if (!(__left == 0)) \134libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \135"VERIFY0(%s) failed (%lld)", #LEFT, \136(u_longlong_t)__left); \137} while (0)138139#define VERIFY0P(LEFT) \140do { \141const uintptr_t __left = (uintptr_t)(LEFT); \142if (!(__left == 0)) \143libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \144"VERIFY0P(%s) failed (%p)", #LEFT, \145(void *)__left); \146} while (0)147148/*149* This is just here because cstyle gets upset about #LEFT150* on a newline.151*/152153/* BEGIN CSTYLED */154#define VERIFY3BF(LEFT, OP, RIGHT, STR, ...) \155do { \156const boolean_t __left = (boolean_t)!!(LEFT); \157const boolean_t __right = (boolean_t)!!(RIGHT); \158if (!(__left OP __right)) \159libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \160"VERIFY3B(%s, %s, %s) failed " \161"(%d %s %d) " STR, #LEFT, #OP, #RIGHT, \162__left, #OP, __right, \163__VA_ARGS__); \164} while (0)165166#define VERIFY3SF(LEFT, OP, RIGHT, STR, ...) \167do { \168const int64_t __left = (int64_t)(LEFT); \169const int64_t __right = (int64_t)(RIGHT); \170if (!(__left OP __right)) \171libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \172"VERIFY3S(%s, %s, %s) failed " \173"(%lld %s %lld) " STR, #LEFT, #OP, #RIGHT, \174(longlong_t)__left, #OP, (longlong_t)__right, \175__VA_ARGS__); \176} while (0)177178#define VERIFY3UF(LEFT, OP, RIGHT, STR, ...) \179do { \180const uint64_t __left = (uint64_t)(LEFT); \181const uint64_t __right = (uint64_t)(RIGHT); \182if (!(__left OP __right)) \183libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \184"VERIFY3U(%s, %s, %s) failed " \185"(%llu %s %llu) " STR, #LEFT, #OP, #RIGHT, \186(u_longlong_t)__left, #OP, (u_longlong_t)__right, \187__VA_ARGS__); \188} while (0)189190#define VERIFY3PF(LEFT, OP, RIGHT, STR, ...) \191do { \192const uintptr_t __left = (uintptr_t)(LEFT); \193const uintptr_t __right = (uintptr_t)(RIGHT); \194if (!(__left OP __right)) \195libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \196"VERIFY3P(%s, %s, %s) failed " \197"(%p %s %p) " STR, #LEFT, #OP, #RIGHT, \198(void *)__left, #OP, (void *)__right, \199__VA_ARGS__); \200} while (0)201/* END CSTYLED */202203#define VERIFY0F(LEFT, STR, ...) \204do { \205const int64_t __left = (int64_t)(LEFT); \206if (!(__left == 0)) \207libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \208"VERIFY0(%s) failed (%lld) " STR, #LEFT, \209(longlong_t)__left, __VA_ARGS__); \210} while (0)211212#define VERIFY0PF(LEFT, STR, ...) \213do { \214const uintptr_t __left = (uintptr_t)(LEFT); \215if (!(__left == 0)) \216libspl_assertf(__FILE__, __FUNCTION__, __LINE__, \217"VERIFY0P(%s) failed (%p) " STR, #LEFT, \218(void *)__left, __VA_ARGS__); \219} while (0)220221#ifdef assert222#undef assert223#endif224225#ifdef NDEBUG226#define ASSERT3B(x, y, z) \227((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))228#define ASSERT3S(x, y, z) \229((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))230#define ASSERT3U(x, y, z) \231((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))232#define ASSERT3P(x, y, z) \233((void) sizeof ((uintptr_t)(x)), (void) sizeof ((uintptr_t)(z)))234#define ASSERT0(x) ((void) sizeof ((uintptr_t)(x)))235#define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))236#define ASSERT3BF(x, y, z, str, ...) ASSERT3B(x, y, z)237#define ASSERT3SF(x, y, z, str, ...) ASSERT3S(x, y, z)238#define ASSERT3UF(x, y, z, str, ...) ASSERT3U(x, y, z)239#define ASSERT3PF(x, y, z, str, ...) ASSERT3P(x, y, z)240#define ASSERT0P(x) ((void) sizeof ((uintptr_t)(x)))241#define ASSERT0PF(x, str, ...) ASSERT0P(x)242#define ASSERT0F(x, str, ...) ASSERT0(x)243#define ASSERT(x) ((void) sizeof ((uintptr_t)(x)))244#define ASSERTF(x, str, ...) ASSERT(x)245#define assert(x) ((void) sizeof ((uintptr_t)(x)))246#define IMPLY(A, B) \247((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))248#define EQUIV(A, B) \249((void) sizeof ((uintptr_t)(A)), (void) sizeof ((uintptr_t)(B)))250#else251#define ASSERT3B VERIFY3B252#define ASSERT3S VERIFY3S253#define ASSERT3U VERIFY3U254#define ASSERT3P VERIFY3P255#define ASSERT0 VERIFY0256#define ASSERT0P VERIFY0P257#define ASSERT3BF VERIFY3BF258#define ASSERT3SF VERIFY3SF259#define ASSERT3UF VERIFY3UF260#define ASSERT3PF VERIFY3PF261#define ASSERT0PF VERIFY0PF262#define ASSERT0F VERIFY0F263#define ASSERT VERIFY264#define ASSERTF VERIFYF265#define assert VERIFY266#define IMPLY(A, B) \267((void)(((!(A)) || (B)) || \268libspl_assert("(" #A ") implies (" #B ")", \269__FILE__, __FUNCTION__, __LINE__)))270#define EQUIV(A, B) VERIFY3B(A, ==, B)271272#endif /* NDEBUG */273274#endif /* _LIBSPL_ASSERT_H */275276277