1 // 2 // Copyright (c) 2008 Travis Geiselbrecht 3 // Copyright 2016 The Fuchsia Authors 4 // 5 // Use of this source code is governed by a MIT-style 6 // license that can be found in the LICENSE file or at 7 // https://opensource.org/licenses/MIT 8 // 9 #pragma once 10 11 #include <lk/compiler.h> 12 #include <lk/debug.h> 13 14 // Assert that |x| is true, else panic. 15 // 16 // ASSERT is always enabled and |x| will be evaluated regardless of any build arguments. 17 #define ASSERT(x) \ 18 do { \ 19 if (unlikely(!(x))) { \ 20 assert_fail(__FILE__, __LINE__, #x); \ 21 } \ 22 } while (0) 23 24 // Assert that |x| is true, else panic with the given message. 25 // 26 // ASSERT_MSG is always enabled and |x| will be evaluated regardless of any build arguments. 27 #define ASSERT_MSG(x, msg, msgargs...) \ 28 do { \ 29 if (unlikely(!(x))) { \ 30 assert_fail_msg(__FILE__, __LINE__, #x, msg, ##msgargs); \ 31 } \ 32 } while (0) 33 34 35 // DEBUG_ASSERT_IMPLEMENTED is intended to be used to conditionalize code that is logically part of 36 // a debug assert. It's useful for performing complex consistency checks that are difficult to work 37 // into a DEBUG_ASSERT statement. 38 #define DEBUG_ASSERT_IMPLEMENTED (LK_DEBUGLEVEL > 1) 39 40 // Assert that |x| is true, else panic. 41 // 42 // Depending on build arguments, DEBUG_ASSERT may or may not be enabled. When disabled, |x| will not 43 // be evaluated. 44 #define DEBUG_ASSERT(x) \ 45 do { \ 46 if (DEBUG_ASSERT_IMPLEMENTED && unlikely(!(x))) { \ 47 assert_fail(__FILE__, __LINE__, #x); \ 48 } \ 49 } while (0) 50 51 // Assert that |x| is true, else panic with the given message. 52 // 53 // Depending on build arguments, DEBUG_ASSERT_MSG may or may not be enabled. When disabled, |x| will 54 // not be evaluated. 55 #define DEBUG_ASSERT_MSG(x, msg, msgargs...) \ 56 do { \ 57 if (DEBUG_ASSERT_IMPLEMENTED && unlikely(!(x))) { \ 58 assert_fail_msg(__FILE__, __LINE__, #x, msg, ##msgargs); \ 59 } \ 60 } while (0) 61 62 // implement _COND versions of DEBUG_ASSERT which only emit the body if 63 // DEBUG_ASSERT_IMPLEMENTED is set 64 #if DEBUG_ASSERT_IMPLEMENTED 65 #define DEBUG_ASSERT_COND(x) DEBUG_ASSERT(x) 66 #define DEBUG_ASSERT_MSG_COND(x, msg, msgargs...) DEBUG_ASSERT_MSG(x, msg, msgargs) 67 #else 68 #define DEBUG_ASSERT_COND(x) \ 69 do { \ 70 } while (0) 71 #define DEBUG_ASSERT_MSG_COND(x, msg, msgargs...) \ 72 do { \ 73 } while (0) 74 #endif 75 76 // make sure static_assert() is defined, even in C 77 #if !defined(__cplusplus) && !defined(static_assert) 78 #define static_assert(e, msg) _Static_assert(e, msg) 79 #endif 80 81 // Use DEBUG_ASSERT or ASSERT instead. 82 // 83 // assert() is defined only because third-party code used in the kernel expects it. 84 #define assert(x) DEBUG_ASSERT(x) 85 86 __BEGIN_CDECLS 87 88 // The following functions are called when an assert fails. 89 void assert_fail(const char *file, int line, const char *expression) __NO_RETURN __NO_INLINE; 90 void assert_fail_msg(const char *file, int line, const char *expression, const char *fmt, 91 ...) __PRINTFLIKE(4, 5) __NO_RETURN __NO_INLINE; 92 93 __END_CDECLS 94