Skip to content

Commit 674f9d5

Browse files
Add ASSUME(expr). Set -ABORT_ON_ASSUME_FAIL when configured with --enable-debug or --enable-fuzz.
1 parent 6a97e8a commit 674f9d5

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

configure.ac

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ if test "x$enable_debug" = xyes; then
291291

292292
AX_CHECK_PREPROC_FLAG([-DDEBUG],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DDEBUG"]],,[[$CXXFLAG_WERROR]])
293293
AX_CHECK_PREPROC_FLAG([-DDEBUG_LOCKORDER],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DDEBUG_LOCKORDER"]],,[[$CXXFLAG_WERROR]])
294+
AX_CHECK_PREPROC_FLAG([-DABORT_ON_FAILED_ASSUME],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DABORT_ON_FAILED_ASSUME"]],,[[$CXXFLAG_WERROR]])
294295
AX_CHECK_COMPILE_FLAG([-ftrapv],[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -ftrapv"],,[[$CXXFLAG_WERROR]])
295296
fi
296297

@@ -1017,6 +1018,7 @@ if test "x$enable_fuzz" = "xyes"; then
10171018
use_bench=no
10181019
use_upnp=no
10191020
use_zmq=no
1021+
AX_CHECK_PREPROC_FLAG([-DABORT_ON_FAILED_ASSUME],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DABORT_ON_FAILED_ASSUME"]],,[[$CXXFLAG_WERROR]])
10201022
else
10211023
BITCOIN_QT_INIT
10221024

src/util/check.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef BITCOIN_UTIL_CHECK_H
66
#define BITCOIN_UTIL_CHECK_H
77

8+
#include <config/bitcoin-config.h>
89
#include <tinyformat.h>
910

1011
#include <stdexcept>
@@ -38,4 +39,56 @@ class NonFatalCheckError : public std::runtime_error
3839
} \
3940
} while (false)
4041

42+
/**
43+
* ASSUME(expression)
44+
*
45+
* ASSUME(...) is used to document assumptions.
46+
*
47+
* Bitcoin Core is always compiled with assertions enabled. assert(...)
48+
* is thus only appropriate for documenting critical assumptions
49+
* where a failed assumption should lead to immediate abortion also
50+
* in production environments.
51+
*
52+
* ASSUME(...) works like assert(...) if -DABORT_ON_FAILED_ASSUME
53+
* and is side-effect safe.
54+
*
55+
* More specifically:
56+
*
57+
* * If compiled with -DABORT_ON_FAILED_ASSUME (set by --enable-debug
58+
* and --enable-fuzz): Evaluate expression and abort if expression is
59+
* false.
60+
*
61+
* * Otherwise:
62+
* Evaluate expression and continue execution.
63+
*
64+
* ABORT_ON_FAILED_ASSUME should not be set in production environments.
65+
*
66+
* Example
67+
* =======
68+
* int main(void) {
69+
* ASSUME(IsFoo());
70+
* ...
71+
* }
72+
*
73+
* If !IsFoo() and -DABORT_ON_FAILED_ASSUME, then:
74+
* filename.cpp:123: main: ASSUME(IsFoo()) failed.
75+
* Aborted
76+
* Otherwise the execution continues.
77+
*/
78+
79+
#ifdef ABORT_ON_FAILED_ASSUME
80+
#define ACTION_ON_FAILED_ASSUME std::abort();
81+
#else
82+
#define ACTION_ON_FAILED_ASSUME
83+
#endif
84+
85+
#define ASSUME(expression) \
86+
do { \
87+
if (!(expression)) { \
88+
tfm::format(std::cerr, "%s:%d: %s: ASSUME(%s) failed. You may report this issue here: %s\n", \
89+
__FILE__, __LINE__, __func__, #expression, PACKAGE_BUGREPORT); \
90+
ACTION_ON_FAILED_ASSUME \
91+
} \
92+
} while (false)
93+
4194
#endif // BITCOIN_UTIL_CHECK_H

0 commit comments

Comments
 (0)