aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2020-06-08 08:47:10 -0400
committerMarcoFalke <falke.marco@gmail.com>2020-06-15 07:39:08 -0400
commitfa6ef701adba1cb48535cac25fd43c742a82e40d (patch)
tree260e6b7232c595094dea9e545e7e9e5dbed17d12
parentfa457fbd3387661e1973a8f4e5cc2def79e0c625 (diff)
downloadbitcoin-fa6ef701adba1cb48535cac25fd43c742a82e40d.tar.xz
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.
-rw-r--r--src/test/util/mining.cpp4
-rw-r--r--src/test/util/setup_common.h1
-rw-r--r--src/util/check.h12
-rwxr-xr-xtest/lint/lint-assertions.sh2
4 files changed, 15 insertions, 4 deletions
diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp
index dac7f1a07b..b0c74954db 100644
--- a/src/test/util/mining.cpp
+++ b/src/test/util/mining.cpp
@@ -11,6 +11,7 @@
#include <node/context.h>
#include <pow.h>
#include <script/standard.h>
+#include <util/check.h>
#include <validation.h>
CTxIn generatetoaddress(const NodeContext& node, const std::string& address)
@@ -39,9 +40,8 @@ CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
{
- assert(node.mempool);
auto block = std::make_shared<CBlock>(
- BlockAssembler{*node.mempool, Params()}
+ BlockAssembler{*Assert(node.mempool), Params()}
.CreateNewBlock(coinbase_scriptPubKey)
->block);
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index d5cda8a95b..b70039e848 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -13,6 +13,7 @@
#include <random.h>
#include <scheduler.h>
#include <txmempool.h>
+#include <util/check.h>
#include <util/string.h>
#include <type_traits>
diff --git a/src/util/check.h b/src/util/check.h
index 5cc078b36b..3d534fd33e 100644
--- a/src/util/check.h
+++ b/src/util/check.h
@@ -25,7 +25,7 @@ class NonFatalCheckError : public std::runtime_error
* - where the condition is assumed to be true, not for error handling or validating user input
* - where a failure to fulfill the condition is recoverable and does not abort the program
*
- * For example in RPC code, where it is undersirable to crash the whole program, this can be generally used to replace
+ * For example in RPC code, where it is undesirable to crash the whole program, this can be generally used to replace
* asserts or recoverable logic errors. A NonFatalCheckError in RPC code is caught and passed as a string to the RPC
* caller, which can then report the issue to the developers.
*/
@@ -46,4 +46,14 @@ class NonFatalCheckError : public std::runtime_error
#error "Cannot compile without assertions!"
#endif
+/** Helper for Assert(). TODO remove in C++14 and replace `decltype(get_pure_r_value(val))` with `T` (templated lambda) */
+template <typename T>
+T get_pure_r_value(T&& val)
+{
+ 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 check; }()
+
#endif // BITCOIN_UTIL_CHECK_H
diff --git a/test/lint/lint-assertions.sh b/test/lint/lint-assertions.sh
index 1aacc09bcc..d30a8ca231 100755
--- a/test/lint/lint-assertions.sh
+++ b/test/lint/lint-assertions.sh
@@ -23,7 +23,7 @@ fi
# Macro CHECK_NONFATAL(condition) should be used instead of assert for RPC code, where it
# is undesirable to crash the whole program. See: src/util/check.h
# src/rpc/server.cpp is excluded from this check since it's mostly meta-code.
-OUTPUT=$(git grep -nE 'assert *\(.*\);' -- "src/rpc/" "src/wallet/rpc*" ":(exclude)src/rpc/server.cpp")
+OUTPUT=$(git grep -nE '\<(A|a)ssert *\(.*\);' -- "src/rpc/" "src/wallet/rpc*" ":(exclude)src/rpc/server.cpp")
if [[ ${OUTPUT} != "" ]]; then
echo "CHECK_NONFATAL(condition) should be used instead of assert for RPC code."
echo