Skip to content

Commit fa6ef70

Browse files
author
MarcoFalke
committed
util: Add Assert identity function
The utility is primarily useful to dereference pointer types, which are known to be not null at that time. For example, the ArgsManager is known to exist when the wallets are started. Instead of silently relying on that assumption, Assert can be used to abort the program and avoid UB should the assumption ever be violated.
1 parent fa457fb commit fa6ef70

File tree

4 files changed

+15
-4
lines changed

4 files changed

+15
-4
lines changed

src/test/util/mining.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <node/context.h>
1212
#include <pow.h>
1313
#include <script/standard.h>
14+
#include <util/check.h>
1415
#include <validation.h>
1516

1617
CTxIn generatetoaddress(const NodeContext& node, const std::string& address)
@@ -39,9 +40,8 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
3940

4041
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
4142
{
42-
assert(node.mempool);
4343
auto block = std::make_shared<CBlock>(
44-
BlockAssembler{*node.mempool, Params()}
44+
BlockAssembler{*Assert(node.mempool), Params()}
4545
.CreateNewBlock(coinbase_scriptPubKey)
4646
->block);
4747

src/test/util/setup_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <random.h>
1414
#include <scheduler.h>
1515
#include <txmempool.h>
16+
#include <util/check.h>
1617
#include <util/string.h>
1718

1819
#include <type_traits>

src/util/check.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class NonFatalCheckError : public std::runtime_error
2525
* - where the condition is assumed to be true, not for error handling or validating user input
2626
* - where a failure to fulfill the condition is recoverable and does not abort the program
2727
*
28-
* For example in RPC code, where it is undersirable to crash the whole program, this can be generally used to replace
28+
* For example in RPC code, where it is undesirable to crash the whole program, this can be generally used to replace
2929
* asserts or recoverable logic errors. A NonFatalCheckError in RPC code is caught and passed as a string to the RPC
3030
* caller, which can then report the issue to the developers.
3131
*/
@@ -46,4 +46,14 @@ class NonFatalCheckError : public std::runtime_error
4646
#error "Cannot compile without assertions!"
4747
#endif
4848

49+
/** Helper for Assert(). TODO remove in C++14 and replace `decltype(get_pure_r_value(val))` with `T` (templated lambda) */
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+
#define Assert(val) [&]() -> decltype(get_pure_r_value(val))& { auto& check = (val); assert(#val && check); return check; }()
58+
4959
#endif // BITCOIN_UTIL_CHECK_H

test/lint/lint-assertions.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fi
2323
# Macro CHECK_NONFATAL(condition) should be used instead of assert for RPC code, where it
2424
# is undesirable to crash the whole program. See: src/util/check.h
2525
# src/rpc/server.cpp is excluded from this check since it's mostly meta-code.
26-
OUTPUT=$(git grep -nE 'assert *\(.*\);' -- "src/rpc/" "src/wallet/rpc*" ":(exclude)src/rpc/server.cpp")
26+
OUTPUT=$(git grep -nE '\<(A|a)ssert *\(.*\);' -- "src/rpc/" "src/wallet/rpc*" ":(exclude)src/rpc/server.cpp")
2727
if [[ ${OUTPUT} != "" ]]; then
2828
echo "CHECK_NONFATAL(condition) should be used instead of assert for RPC code."
2929
echo

0 commit comments

Comments
 (0)