1/* @title: Assertions */
2#include <compiler.h>
3#include <console/panic.h>
4
5/*
6 * Notes on kassert naming:
7 *
8 * no suffix - always fires, unhookable "the big panic"
9 * _debug - fires on DEBUG_ASSERT, hookable "panic for debugging"
10 * _oops - always fires, hookable "small invariant broken"
11 *
12 */
13
14#define _kassert_pick(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, NAME, ...) \
15 NAME
16
17#define _kassert_1(prefix, x) \
18 do { \
19 if (unlikely(!(x))) { \
20 panic(prefix "Assertion \"" #x "\" failed"); \
21 __builtin_unreachable(); \
22 } \
23 } while (0)
24
25#define _kassert_n(prefix, x, fmt, ...) \
26 do { \
27 if (unlikely(!(x))) { \
28 panic(prefix "Assertion \"" #x "\" failed with message: " fmt, \
29 ##__VA_ARGS__); \
30 __builtin_unreachable(); \
31 } \
32 } while (0)
33
34#define _kassert_oops_1(prefix, x) \
35 do { \
36 if (unlikely(!(x))) { \
37 panic(prefix "Oops, assertion \"" #x "\" failed"); \
38 __builtin_unreachable(); \
39 } \
40 } while (0)
41
42#define _kassert_oops_n(prefix, x, fmt, ...) \
43 do { \
44 if (unlikely(!(x))) { \
45 panic(prefix "Oops, assertion \"" #x \
46 "\" failed with message: " fmt, \
47 ##__VA_ARGS__); \
48 __builtin_unreachable(); \
49 } \
50 } while (0)
51
52#define _kassert_debug_1(prefix, x) \
53 do { \
54 if (unlikely(!(x))) { \
55 panic(prefix "Debug assertion \"" #x "\" failed"); \
56 __builtin_unreachable(); \
57 } \
58 } while (0)
59
60#define _kassert_debug_n(prefix, x, fmt, ...) \
61 do { \
62 if (unlikely(!(x))) { \
63 panic(prefix "Debug assertion \"" #x \
64 "\" failed with message: " fmt, \
65 ##__VA_ARGS__); \
66 __builtin_unreachable(); \
67 } \
68 } while (0)
69
70#define _kassert_dispatch(name, prefix, ...) \
71 _kassert_pick(__VA_ARGS__, name##_n, name##_n, name##_n, name##_n, \
72 name##_n, name##_n, name##_n, name##_n, name##_n, name##_n, \
73 name##_1)(prefix, __VA_ARGS__)
74
75#define _kassert_fail(prefix, ...) \
76 do { \
77 panic(prefix __VA_ARGS__); \
78 __builtin_unreachable(); \
79 } while (0)
80
81#define kassert(...) _kassert_dispatch(_kassert, "", __VA_ARGS__)
82
83#define kassert_unreachable(...) _kassert_fail("unreachable! ", ##__VA_ARGS__)
84#define kassert_unimplemented(...) \
85 _kassert_fail("unimplemented! ", ##__VA_ARGS__)
86#define kassert_todo(...) _kassert_fail("TODO: ", ##__VA_ARGS__)
87
88#ifdef DEBUG_ASSERT
89
90#define kassert_debug(...) \
91 _kassert_dispatch(_kassert_debug, "DEBUG ", __VA_ARGS__)
92
93#define kassert_debug_unreachable(...) \
94 _kassert_fail("DEBUG unreachable! ", ##__VA_ARGS__)
95#define kassert_debug_unimplemented(...) \
96 _kassert_fail("DEBUG unimplemented! ", ##__VA_ARGS__)
97#define kassert_debug_todo(...) _kassert_fail("DEBUG TODO: ", ##__VA_ARGS__)
98
99#else
100
101#define kassert_debug(...) ((void) 0)
102#define kassert_debug_unreachable(...) ((void) 0)
103#define kassert_debug_unimplemented(...) ((void) 0)
104#define kassert_debug_todo(...) ((void) 0)
105
106#endif
107