Branch data Line data Source code
# 1 : : // Copyright (c) 2019-2020 The Bitcoin Core developers # 2 : : // Distributed under the MIT software license, see the accompanying # 3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php. # 4 : : # 5 : : #ifndef BITCOIN_UTIL_CHECK_H # 6 : : #define BITCOIN_UTIL_CHECK_H # 7 : : # 8 : : #if defined(HAVE_CONFIG_H) # 9 : : #include <config/bitcoin-config.h> # 10 : : #endif # 11 : : # 12 : : #include <tinyformat.h> # 13 : : # 14 : : #include <stdexcept> # 15 : : # 16 : : class NonFatalCheckError : public std::runtime_error # 17 : : { # 18 : : using std::runtime_error::runtime_error; # 19 : : }; # 20 : : # 21 : : /** # 22 : : * Throw a NonFatalCheckError when the condition evaluates to false # 23 : : * # 24 : : * This should only be used # 25 : : * - where the condition is assumed to be true, not for error handling or validating user input # 26 : : * - where a failure to fulfill the condition is recoverable and does not abort the program # 27 : : * # 28 : : * For example in RPC code, where it is undesirable to crash the whole program, this can be generally used to replace # 29 : : * asserts or recoverable logic errors. A NonFatalCheckError in RPC code is caught and passed as a string to the RPC # 30 : : * caller, which can then report the issue to the developers. # 31 : : */ # 32 : : #define CHECK_NONFATAL(condition) \ # 33 : 4456903 : do { \ # 34 : 4456832 : if (!(condition)) { \ # 35 : 1 : throw NonFatalCheckError( \ # 36 : 1 : strprintf("%s:%d (%s)\n" \ # 37 : 1 : "Internal bug detected: '%s'\n" \ # 38 : 1 : "You may report this issue here: %s\n", \ # 39 : 1 : __FILE__, __LINE__, __func__, \ # 40 : 1 : (#condition), \ # 41 : 1 : PACKAGE_BUGREPORT)); \ # 42 : 1 : } \ # 43 : 4456832 : } while (false) # 44 : : # 45 : : #if defined(NDEBUG) # 46 : : #error "Cannot compile without assertions!" # 47 : : #endif # 48 : : # 49 : : /** Helper for Assert() */ # 50 : : template <typename T> # 51 : : T get_pure_r_value(T&& val) # 52 : : { # 53 : : return std::forward<T>(val); # 54 : : } # 55 : : # 56 : : /** Identity function. Abort if the value compares equal to zero */ # 57 : 5714495 : #define Assert(val) ([&]() -> decltype(get_pure_r_value(val)) { auto&& check = (val); assert(#val && check); return std::forward<decltype(get_pure_r_value(val))>(check); }()) # 58 : : # 59 : : /** # 60 : : * Assume is the identity function. # 61 : : * # 62 : : * - Should be used to run non-fatal checks. In debug builds it behaves like # 63 : : * Assert()/assert() to notify developers and testers about non-fatal errors. # 64 : : * In production it doesn't warn or log anything. # 65 : : * - For fatal errors, use Assert(). # 66 : : * - For non-fatal errors in interactive sessions (e.g. RPC or command line # 67 : : * interfaces), CHECK_NONFATAL() might be more appropriate. # 68 : : */ # 69 : : #ifdef ABORT_ON_FAILED_ASSUME # 70 : 63013 : #define Assume(val) Assert(val) # 71 : : #else # 72 : : #define Assume(val) ([&]() -> decltype(get_pure_r_value(val)) { auto&& check = (val); return std::forward<decltype(get_pure_r_value(val))>(check); }()) # 73 : : #endif # 74 : : # 75 : : #endif // BITCOIN_UTIL_CHECK_H