@@ -57,26 +57,38 @@ static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback *
57
57
} while(0)
58
58
#endif
59
59
60
- /* VERIFY_CHECK is like assert(), but gated by -DVERIFY, and always
61
- * evaluated (even without -DVERIFY) to minimize differences between
62
- * the two modes if conditions with side effects are accidentally
63
- * included.
60
+ #ifdef CHECK_SIDE_EFFECT_FREE
61
+ /* When our compiler is capable to optimizing away references to variables
62
+ * that control execution of a side-effect free statement, use this to
63
+ * check that VERIFY_CHECK conditions are safe.
64
+ *
65
+ * Credit to: https://stackoverflow.com/a/35294344 */
66
+ extern int secp256k1_not_supposed_to_survive ;
67
+ #define ASSERT_NO_SIDE_EFFECT (cond ) do { (void)(secp256k1_not_supposed_to_survive || (cond)); } while(0)
68
+ #else
69
+ /* If we can't use that, just run it in an unexecuted branch, to make sure it is still
70
+ * syntactically valid. */
71
+ #define ASSERT_NO_SIDE_EFFECT (cond ) do { if (0) { (void)(cond); } } while(0)
72
+ #endif
73
+
74
+ /* VERIFY_CHECK is like assert(), but gated by -DVERIFY, and verified for
75
+ * side effect-freeness under -DCHECK_SIDE_EFFECT_FREE.
64
76
*
65
77
* VERIFY_CHECK_ONLY is similar, but less safe: it has no effect outside
66
78
* of -DVERIFY, and thus can be used with expensive conditions, or even
67
79
* conditions that wouldn't compile outside -DVERIFY). */
68
80
#if defined(COVERAGE )
69
- #define VERIFY_CHECK (check )
70
- #define VERIFY_CHECK_ONLY (check )
71
- #define VERIFY_SETUP (stmt )
81
+ # define VERIFY_CHECK (check )
82
+ # define VERIFY_CHECK_ONLY (check )
83
+ # define VERIFY_SETUP (stmt )
72
84
#elif defined(VERIFY )
73
- #define VERIFY_CHECK CHECK
74
- #define VERIFY_CHECK_ONLY CHECK
75
- #define VERIFY_SETUP (stmt ) do { stmt; } while(0)
85
+ # define VERIFY_CHECK ( cond ) do { ASSERT_NO_SIDE_EFFECT(cond); CHECK(cond); } while (0)
86
+ # define VERIFY_CHECK_ONLY CHECK
87
+ # define VERIFY_SETUP (stmt ) do { stmt; } while(0)
76
88
#else
77
- #define VERIFY_CHECK (cond ) do { (void)( cond); } while(0)
78
- #define VERIFY_CHECK_ONLY (cond )
79
- #define VERIFY_SETUP (stmt )
89
+ # define VERIFY_CHECK (cond ) do { ASSERT_NO_SIDE_EFFECT( cond); } while (0)
90
+ # define VERIFY_CHECK_ONLY (cond )
91
+ # define VERIFY_SETUP (stmt )
80
92
#endif
81
93
82
94
/* Define `VG_UNDEF` and `VG_CHECK` when VALGRIND is defined */
0 commit comments