Coverage Report

Created: 2022-11-24 06:56

/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