/* * Runtime assertion checking * (C) 2010,2018 Jack Lloyd * 2017 Simon Warta (Kullo GmbH) * * Botan is released under the Simplified BSD License (see license.txt) */ #ifndef BOTAN_ASSERTION_CHECKING_H_ #define BOTAN_ASSERTION_CHECKING_H_ #include #include namespace Botan { /** * Called when an assertion fails * Throws an Exception object */ BOTAN_NORETURN void BOTAN_PUBLIC_API(2,0) assertion_failure(const char* expr_str, const char* assertion_made, const char* func, const char* file, int line); /** * Called when an invalid argument is used * Throws Invalid_Argument */ BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_argument(const char* message, const char* func, const char* file); #define BOTAN_ARG_CHECK(expr, msg) \ do { if(!(expr)) Botan::throw_invalid_argument(msg, __func__, __FILE__); } while(0) /** * Called when an invalid state is encountered * Throws Invalid_State */ BOTAN_NORETURN void BOTAN_UNSTABLE_API throw_invalid_state(const char* message, const char* func, const char* file); #define BOTAN_STATE_CHECK(expr) \ do { if(!(expr)) Botan::throw_invalid_state(#expr, __func__, __FILE__); } while(0) /** * Make an assertion */ #define BOTAN_ASSERT(expr, assertion_made) \ do { \ if(!(expr)) \ Botan::assertion_failure(#expr, \ assertion_made, \ __func__, \ __FILE__, \ __LINE__); \ } while(0) /** * Make an assertion */ #define BOTAN_ASSERT_NOMSG(expr) \ do { \ if(!(expr)) \ Botan::assertion_failure(#expr, \ "", \ __func__, \ __FILE__, \ __LINE__); \ } while(0) /** * Assert that value1 == value2 */ #define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made) \ do { \ if((expr1) != (expr2)) \ Botan::assertion_failure(#expr1 " == " #expr2, \ assertion_made, \ __func__, \ __FILE__, \ __LINE__); \ } while(0) /** * Assert that expr1 (if true) implies expr2 is also true */ #define BOTAN_ASSERT_IMPLICATION(expr1, expr2, msg) \ do { \ if((expr1) && !(expr2)) \ Botan::assertion_failure(#expr1 " implies " #expr2, \ msg, \ __func__, \ __FILE__, \ __LINE__); \ } while(0) /** * Assert that a pointer is not null */ #define BOTAN_ASSERT_NONNULL(ptr) \ do { \ if((ptr) == nullptr) \ Botan::assertion_failure(#ptr " is not null", \ "", \ __func__, \ __FILE__, \ __LINE__); \ } while(0) #if defined(BOTAN_ENABLE_DEBUG_ASSERTS) #define BOTAN_DEBUG_ASSERT(expr) BOTAN_ASSERT_NOMSG(expr) #else #define BOTAN_DEBUG_ASSERT(expr) do {} while(0) #endif /** * Mark variable as unused. Takes between 1 and 9 arguments and marks all as unused, * e.g. BOTAN_UNUSED(a); or BOTAN_UNUSED(x, y, z); */ #define _BOTAN_UNUSED_IMPL1(a) static_cast(a) #define _BOTAN_UNUSED_IMPL2(a, b) static_cast(a); _BOTAN_UNUSED_IMPL1(b) #define _BOTAN_UNUSED_IMPL3(a, b, c) static_cast(a); _BOTAN_UNUSED_IMPL2(b, c) #define _BOTAN_UNUSED_IMPL4(a, b, c, d) static_cast(a); _BOTAN_UNUSED_IMPL3(b, c, d) #define _BOTAN_UNUSED_IMPL5(a, b, c, d, e) static_cast(a); _BOTAN_UNUSED_IMPL4(b, c, d, e) #define _BOTAN_UNUSED_IMPL6(a, b, c, d, e, f) static_cast(a); _BOTAN_UNUSED_IMPL5(b, c, d, e, f) #define _BOTAN_UNUSED_IMPL7(a, b, c, d, e, f, g) static_cast(a); _BOTAN_UNUSED_IMPL6(b, c, d, e, f, g) #define _BOTAN_UNUSED_IMPL8(a, b, c, d, e, f, g, h) static_cast(a); _BOTAN_UNUSED_IMPL7(b, c, d, e, f, g, h) #define _BOTAN_UNUSED_IMPL9(a, b, c, d, e, f, g, h, i) static_cast(a); _BOTAN_UNUSED_IMPL8(b, c, d, e, f, g, h, i) #define _BOTAN_UNUSED_GET_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, IMPL_NAME, ...) IMPL_NAME #define BOTAN_UNUSED(...) _BOTAN_UNUSED_GET_IMPL(__VA_ARGS__, \ _BOTAN_UNUSED_IMPL9, \ _BOTAN_UNUSED_IMPL8, \ _BOTAN_UNUSED_IMPL7, \ _BOTAN_UNUSED_IMPL6, \ _BOTAN_UNUSED_IMPL5, \ _BOTAN_UNUSED_IMPL4, \ _BOTAN_UNUSED_IMPL3, \ _BOTAN_UNUSED_IMPL2, \ _BOTAN_UNUSED_IMPL1, \ unused dummy rest value \ ) /* we got an one of _BOTAN_UNUSED_IMPL*, now call it */ (__VA_ARGS__) } #endif