util/check: stop using lambda for Assert/Assume
This commit is contained in:
1 parent
7c9fe25c16
commit
2ef47ba6c5
4 files changed
+65
-8
No files matched your search
@@ -621,6 +621,7 @@ libbitcoin_util_a_SOURCES = \
|
|||||||
util/asmap.cpp \
|
util/asmap.cpp \
|
||||||
util/bip32.cpp \
|
util/bip32.cpp \
|
||||||
util/bytevectorhash.cpp \
|
util/bytevectorhash.cpp \
|
||||||
|
util/check.cpp \
|
||||||
util/error.cpp \
|
util/error.cpp \
|
||||||
util/fees.cpp \
|
util/fees.cpp \
|
||||||
util/getuniquepath.cpp \
|
util/getuniquepath.cpp \
|
||||||
@@ -839,6 +840,7 @@ bitcoin_chainstate_SOURCES = \
|
|||||||
uint256.cpp \
|
uint256.cpp \
|
||||||
util/asmap.cpp \
|
util/asmap.cpp \
|
||||||
util/bytevectorhash.cpp \
|
util/bytevectorhash.cpp \
|
||||||
|
util/check.cpp \
|
||||||
util/getuniquepath.cpp \
|
util/getuniquepath.cpp \
|
||||||
util/hasher.cpp \
|
util/hasher.cpp \
|
||||||
util/moneystr.cpp \
|
util/moneystr.cpp \
|
||||||
|
|||||||
@@ -78,6 +78,31 @@ BOOST_AUTO_TEST_CASE(util_datadir)
|
|||||||
BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
|
BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class NoCopyOrMove
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int i;
|
||||||
|
explicit NoCopyOrMove(int i) : i{i} { }
|
||||||
|
|
||||||
|
NoCopyOrMove() = delete;
|
||||||
|
NoCopyOrMove(const NoCopyOrMove&) = delete;
|
||||||
|
NoCopyOrMove(NoCopyOrMove&&) = delete;
|
||||||
|
NoCopyOrMove& operator=(const NoCopyOrMove&) = delete;
|
||||||
|
NoCopyOrMove& operator=(NoCopyOrMove&&) = delete;
|
||||||
|
|
||||||
|
operator bool() const { return i != 0; }
|
||||||
|
|
||||||
|
int get_ip1() { return i + 1; }
|
||||||
|
bool test()
|
||||||
|
{
|
||||||
|
// Check that Assume can be used within a lambda and still call methods
|
||||||
|
[&]() { Assume(get_ip1()); }();
|
||||||
|
return Assume(get_ip1() != 5);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(util_check)
|
BOOST_AUTO_TEST_CASE(util_check)
|
||||||
{
|
{
|
||||||
// Check that Assert can forward
|
// Check that Assert can forward
|
||||||
@@ -89,6 +114,14 @@ BOOST_AUTO_TEST_CASE(util_check)
|
|||||||
// Check that Assume can be used as unary expression
|
// Check that Assume can be used as unary expression
|
||||||
const bool result{Assume(two == 2)};
|
const bool result{Assume(two == 2)};
|
||||||
Assert(result);
|
Assert(result);
|
||||||
|
|
||||||
|
// Check that Assert doesn't require copy/move
|
||||||
|
NoCopyOrMove x{9};
|
||||||
|
Assert(x).i += 3;
|
||||||
|
Assert(x).test();
|
||||||
|
|
||||||
|
// Check nested Asserts
|
||||||
|
BOOST_CHECK_EQUAL(Assert((Assert(x).test() ? 3 : 0)), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(util_criticalsection)
|
BOOST_AUTO_TEST_CASE(util_criticalsection)
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (c) 2022 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <util/check.h>
|
||||||
|
|
||||||
|
#include <tinyformat.h>
|
||||||
|
|
||||||
|
void assertion_fail(const char* file, int line, const char* func, const char* assertion)
|
||||||
|
{
|
||||||
|
auto str = strprintf("%s:%s %s: Assertion `%s' failed.\n", file, line, func, assertion);
|
||||||
|
fwrite(str.data(), 1, str.size(), stderr);
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
+16
-8
@@ -47,14 +47,26 @@ class NonFatalCheckError : public std::runtime_error
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Helper for Assert() */
|
/** Helper for Assert() */
|
||||||
template <typename T>
|
void assertion_fail(const char* file, int line, const char* func, const char* assertion);
|
||||||
T get_pure_r_value(T&& val)
|
|
||||||
|
/** Helper for Assert()/Assume() */
|
||||||
|
template <bool IS_ASSERT, typename T>
|
||||||
|
T&& inline_assertion_check(T&& val, const char* file, int line, const char* func, const char* assertion)
|
||||||
{
|
{
|
||||||
|
if constexpr (IS_ASSERT
|
||||||
|
#ifdef ABORT_ON_FAILED_ASSUME
|
||||||
|
|| true
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
if (!val) {
|
||||||
|
assertion_fail(file, line, func, assertion);
|
||||||
|
}
|
||||||
|
}
|
||||||
return std::forward<T>(val);
|
return std::forward<T>(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Identity function. Abort if the value compares equal to zero */
|
/** Identity function. Abort if the value compares equal to zero */
|
||||||
#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); }())
|
#define Assert(val) inline_assertion_check<true>(val, __FILE__, __LINE__, __func__, #val)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assume is the identity function.
|
* Assume is the identity function.
|
||||||
@@ -66,10 +78,6 @@ T get_pure_r_value(T&& val)
|
|||||||
* - For non-fatal errors in interactive sessions (e.g. RPC or command line
|
* - For non-fatal errors in interactive sessions (e.g. RPC or command line
|
||||||
* interfaces), CHECK_NONFATAL() might be more appropriate.
|
* interfaces), CHECK_NONFATAL() might be more appropriate.
|
||||||
*/
|
*/
|
||||||
#ifdef ABORT_ON_FAILED_ASSUME
|
#define Assume(val) inline_assertion_check<false>(val, __FILE__, __LINE__, __func__, #val)
|
||||||
#define Assume(val) Assert(val)
|
|
||||||
#else
|
|
||||||
#define Assume(val) ([&]() -> decltype(get_pure_r_value(val)) { auto&& check = (val); return std::forward<decltype(get_pure_r_value(val))>(check); }())
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // BITCOIN_UTIL_CHECK_H
|
#endif // BITCOIN_UTIL_CHECK_H
|
||||||
Reference in new issue
Block a user