Botan 3.0.0
Crypto and TLS for C&
assert.h
Go to the documentation of this file.
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
14namespace 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 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 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 do { \
56 if(!(expr)) \
57 Botan::assertion_failure(#expr, \
58 assertion_made, \
59 __func__, \
60 __FILE__, \
61 __LINE__); \
62 } while(0)
63
64/**
65* Make an assertion
66*/
67#define BOTAN_ASSERT_NOMSG(expr) \
68 do { \
69 if(!(expr)) \
70 Botan::assertion_failure(#expr, \
71 "", \
72 __func__, \
73 __FILE__, \
74 __LINE__); \
75 } while(0)
76
77/**
78* Assert that value1 == value2
79*/
80#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made) \
81 do { \
82 if((expr1) != (expr2)) \
83 Botan::assertion_failure(#expr1 " == " #expr2, \
84 assertion_made, \
85 __func__, \
86 __FILE__, \
87 __LINE__); \
88 } 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 do { \
95 if((expr1) && !(expr2)) \
96 Botan::assertion_failure(#expr1 " implies " #expr2, \
97 msg, \
98 __func__, \
99 __FILE__, \
100 __LINE__); \
101 } while(0)
102
103/**
104* Assert that a pointer is not null
105*/
106#define BOTAN_ASSERT_NONNULL(ptr) \
107 do { \
108 if((ptr) == nullptr) \
109 Botan::assertion_failure(#ptr " is not null", \
110 "", \
111 __func__, \
112 __FILE__, \
113 __LINE__); \
114 } 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#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#define _BOTAN_UNUSED_IMPL1(a) static_cast<void>(a)
131#define _BOTAN_UNUSED_IMPL2(a, b) static_cast<void>(a); _BOTAN_UNUSED_IMPL1(b)
132#define _BOTAN_UNUSED_IMPL3(a, b, c) static_cast<void>(a); _BOTAN_UNUSED_IMPL2(b, c)
133#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#define _BOTAN_UNUSED_GET_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, IMPL_NAME, ...) IMPL_NAME
140
141#define BOTAN_UNUSED(...) _BOTAN_UNUSED_GET_IMPL(__VA_ARGS__, \
142 _BOTAN_UNUSED_IMPL9, \
143 _BOTAN_UNUSED_IMPL8, \
144 _BOTAN_UNUSED_IMPL7, \
145 _BOTAN_UNUSED_IMPL6, \
146 _BOTAN_UNUSED_IMPL5, \
147 _BOTAN_UNUSED_IMPL4, \
148 _BOTAN_UNUSED_IMPL3, \
149 _BOTAN_UNUSED_IMPL2, \
150 _BOTAN_UNUSED_IMPL1, \
151 unused dummy rest value \
152 ) /* 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*/
161 {
162#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_unreachable)
163 __builtin_unreachable();
164#elif defined(_MSC_VER) // MSVC
165 __assume(false);
166#else
167 return; // undefined behaviour, just like the others...
168#endif
169 }
170
171}
172
173#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
#define BOTAN_FORCE_INLINE
Definition: compiler.h:167
#define BOTAN_UNSTABLE_API
Definition: compiler.h:44
Definition: alg_id.cpp:12
void throw_invalid_state(const char *expr, const char *func, const char *file)
Definition: assert.cpp:26
void throw_invalid_argument(const char *message, const char *func, const char *file)
Definition: assert.cpp:19
BOTAN_FORCE_INLINE void unreachable()
Definition: assert.h:160
void assertion_failure(const char *expr_str, const char *assertion_made, const char *func, const char *file, int line)
Definition: assert.cpp:33