mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-05-31 16:24:48 +02:00
Merge bitcoin/bitcoin#24714: util/check: Don't use a lambda for Assert/Assume
2ef47ba6c5util/check: stop using lambda for Assert/Assume (Anthony Towns)7c9fe25c16wallet: move Assert() check into constructor (Anthony Towns) Pull request description: Using a lambda creates a couple of odd namespacing issues, in particular making clang's thread safety analysis less helpful, and confusing gcc when calling member functions. Fix this by not using a lambda. Fixes #21596 Fixes #24654 ACKs for top commit: MarcoFalke: ACK2ef47ba6c5🚢 jonatack: Tested re-ACK2ef47ba6c5Tree-SHA512: 4bdbf3215f3d14472df0552362c5eebe8b7eea2d0928a8a41109edd4e0c5f95de6f8220eb2fee8506874e352c003907faf5ef344174795939306a618157b1bae
This commit is contained in:
14
src/util/check.cpp
Normal file
14
src/util/check.cpp
Normal file
@@ -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();
|
||||
}
|
||||
@@ -47,14 +47,26 @@ class NonFatalCheckError : public std::runtime_error
|
||||
#endif
|
||||
|
||||
/** Helper for Assert() */
|
||||
template <typename T>
|
||||
T get_pure_r_value(T&& val)
|
||||
void assertion_fail(const char* file, int line, const char* func, const char* assertion);
|
||||
|
||||
/** 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);
|
||||
}
|
||||
|
||||
/** 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.
|
||||
@@ -66,10 +78,6 @@ T get_pure_r_value(T&& val)
|
||||
* - For non-fatal errors in interactive sessions (e.g. RPC or command line
|
||||
* interfaces), CHECK_NONFATAL() might be more appropriate.
|
||||
*/
|
||||
#ifdef ABORT_ON_FAILED_ASSUME
|
||||
#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
|
||||
#define Assume(val) inline_assertion_check<false>(val, __FILE__, __LINE__, __func__, #val)
|
||||
|
||||
#endif // BITCOIN_UTIL_CHECK_H
|
||||
|
||||
Reference in New Issue
Block a user