/src/botan/build/include/botan/assert.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Runtime assertion checking |
3 | | * (C) 2010,2018 Jack Lloyd |
4 | | * 2017 Simon Warta (Kullo GmbH) |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | #ifndef BOTAN_ASSERTION_CHECKING_H_ |
10 | | #define BOTAN_ASSERTION_CHECKING_H_ |
11 | | |
12 | | #include <botan/build.h> |
13 | | |
14 | | namespace Botan { |
15 | | |
16 | | /** |
17 | | * Called when an assertion fails |
18 | | * Throws an Exception object |
19 | | */ |
20 | | [[noreturn]] void BOTAN_PUBLIC_API(2,0) |
21 | | assertion_failure(const char* expr_str, |
22 | | const char* assertion_made, |
23 | | const char* func, |
24 | | const char* file, |
25 | | int line); |
26 | | |
27 | | /** |
28 | | * Called when an invalid argument is used |
29 | | * Throws Invalid_Argument |
30 | | */ |
31 | | [[noreturn]] void BOTAN_UNSTABLE_API throw_invalid_argument(const char* message, |
32 | | const char* func, |
33 | | const char* file); |
34 | | |
35 | | |
36 | | #define BOTAN_ARG_CHECK(expr, msg) \ |
37 | 311M | do { if(!(expr)) Botan::throw_invalid_argument(msg, __func__, __FILE__); } while(0) |
38 | | |
39 | | /** |
40 | | * Called when an invalid state is encountered |
41 | | * Throws Invalid_State |
42 | | */ |
43 | | [[noreturn]] void BOTAN_UNSTABLE_API throw_invalid_state(const char* message, |
44 | | const char* func, |
45 | | const char* file); |
46 | | |
47 | | |
48 | | #define BOTAN_STATE_CHECK(expr) \ |
49 | 5.57k | do { if(!(expr)) Botan::throw_invalid_state(#expr, __func__, __FILE__); } while(0) |
50 | | |
51 | | /** |
52 | | * Make an assertion |
53 | | */ |
54 | | #define BOTAN_ASSERT(expr, assertion_made) \ |
55 | 1.89G | do { \ |
56 | 1.89G | if(!(expr)) \ |
57 | 1.89G | Botan::assertion_failure(#expr, \ |
58 | 63 | assertion_made, \ |
59 | 63 | __func__, \ |
60 | 63 | __FILE__, \ |
61 | 63 | __LINE__); \ |
62 | 1.89G | } while(0) |
63 | | |
64 | | /** |
65 | | * Make an assertion |
66 | | */ |
67 | | #define BOTAN_ASSERT_NOMSG(expr) \ |
68 | 188M | do { \ |
69 | 188M | if(!(expr)) \ |
70 | 188M | Botan::assertion_failure(#expr, \ |
71 | 0 | "", \ |
72 | 0 | __func__, \ |
73 | 0 | __FILE__, \ |
74 | 0 | __LINE__); \ |
75 | 188M | } while(0) |
76 | | |
77 | | /** |
78 | | * Assert that value1 == value2 |
79 | | */ |
80 | | #define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made) \ |
81 | 152M | do { \ |
82 | 152M | if((expr1) != (expr2)) \ |
83 | 152M | Botan::assertion_failure(#expr1 " == " #expr2, \ |
84 | 0 | assertion_made, \ |
85 | 0 | __func__, \ |
86 | 0 | __FILE__, \ |
87 | 0 | __LINE__); \ |
88 | 152M | } while(0) |
89 | | |
90 | | /** |
91 | | * Assert that expr1 (if true) implies expr2 is also true |
92 | | */ |
93 | | #define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg) \ |
94 | 396M | do { \ |
95 | 790M | if((expr1) && !(expr2)) \ |
96 | 396M | Botan::assertion_failure(#expr1 " implies " #expr2, \ |
97 | 0 | msg, \ |
98 | 0 | __func__, \ |
99 | 0 | __FILE__, \ |
100 | 0 | __LINE__); \ |
101 | 396M | } while(0) |
102 | | |
103 | | /** |
104 | | * Assert that a pointer is not null |
105 | | */ |
106 | | #define BOTAN_ASSERT_NONNULL(ptr) \ |
107 | 28.7k | do { \ |
108 | 28.7k | if((ptr) == nullptr) \ |
109 | 28.7k | Botan::assertion_failure(#ptr " is not null", \ |
110 | 0 | "", \ |
111 | 0 | __func__, \ |
112 | 0 | __FILE__, \ |
113 | 0 | __LINE__); \ |
114 | 28.7k | } while(0) |
115 | | |
116 | | #if defined(BOTAN_ENABLE_DEBUG_ASSERTS) |
117 | | |
118 | | #define BOTAN_DEBUG_ASSERT(expr) BOTAN_ASSERT_NOMSG(expr) |
119 | | |
120 | | #else |
121 | | |
122 | 2.24G | #define BOTAN_DEBUG_ASSERT(expr) do {} while(0) |
123 | | |
124 | | #endif |
125 | | |
126 | | /** |
127 | | * Mark variable as unused. Takes between 1 and 9 arguments and marks all as unused, |
128 | | * e.g. BOTAN_UNUSED(a); or BOTAN_UNUSED(x, y, z); |
129 | | */ |
130 | 1.57G | #define _BOTAN_UNUSED_IMPL1(a) static_cast<void>(a) |
131 | 182M | #define _BOTAN_UNUSED_IMPL2(a, b) static_cast<void>(a); _BOTAN_UNUSED_IMPL1(b) |
132 | 0 | #define _BOTAN_UNUSED_IMPL3(a, b, c) static_cast<void>(a); _BOTAN_UNUSED_IMPL2(b, c) |
133 | 0 | #define _BOTAN_UNUSED_IMPL4(a, b, c, d) static_cast<void>(a); _BOTAN_UNUSED_IMPL3(b, c, d) |
134 | | #define _BOTAN_UNUSED_IMPL5(a, b, c, d, e) static_cast<void>(a); _BOTAN_UNUSED_IMPL4(b, c, d, e) |
135 | | #define _BOTAN_UNUSED_IMPL6(a, b, c, d, e, f) static_cast<void>(a); _BOTAN_UNUSED_IMPL5(b, c, d, e, f) |
136 | | #define _BOTAN_UNUSED_IMPL7(a, b, c, d, e, f, g) static_cast<void>(a); _BOTAN_UNUSED_IMPL6(b, c, d, e, f, g) |
137 | | #define _BOTAN_UNUSED_IMPL8(a, b, c, d, e, f, g, h) static_cast<void>(a); _BOTAN_UNUSED_IMPL7(b, c, d, e, f, g, h) |
138 | | #define _BOTAN_UNUSED_IMPL9(a, b, c, d, e, f, g, h, i) static_cast<void>(a); _BOTAN_UNUSED_IMPL8(b, c, d, e, f, g, h, i) |
139 | 1.57G | #define _BOTAN_UNUSED_GET_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, IMPL_NAME, ...) IMPL_NAME |
140 | | |
141 | 1.57G | #define BOTAN_UNUSED(...) _BOTAN_UNUSED_GET_IMPL(__VA_ARGS__, \ |
142 | 1.57G | _BOTAN_UNUSED_IMPL9, \ |
143 | 1.57G | _BOTAN_UNUSED_IMPL8, \ |
144 | 1.57G | _BOTAN_UNUSED_IMPL7, \ |
145 | 1.57G | _BOTAN_UNUSED_IMPL6, \ |
146 | 1.57G | _BOTAN_UNUSED_IMPL5, \ |
147 | 1.57G | _BOTAN_UNUSED_IMPL4, \ |
148 | 1.57G | _BOTAN_UNUSED_IMPL3, \ |
149 | 1.57G | _BOTAN_UNUSED_IMPL2, \ |
150 | 1.57G | _BOTAN_UNUSED_IMPL1, \ |
151 | 1.57G | unused dummy rest value \ |
152 | 1.57G | ) /* we got an one of _BOTAN_UNUSED_IMPL*, now call it */ (__VA_ARGS__) |
153 | | |
154 | | /* |
155 | | * Define Botan::unreachable() |
156 | | * |
157 | | * There is a pending WG21 proposal for `std::unreachable()` |
158 | | * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0627r3.pdf |
159 | | */ |
160 | | [[noreturn]] BOTAN_FORCE_INLINE void unreachable() |
161 | 0 | { |
162 | 0 | #if defined(__GNUC__) // GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) |
163 | 0 | __builtin_unreachable(); |
164 | 0 | #elif defined(_MSC_VER) // MSVC |
165 | 0 | __assume(false); |
166 | 0 | #else |
167 | 0 | return; // undefined behaviour, just like the others... |
168 | 0 | #endif |
169 | 0 | } |
170 | | |
171 | | } |
172 | | |
173 | | #endif |