xref: /freebsd/contrib/ntp/include/ntp_assert.h (revision b626f5a73a48f44a31a200291b141e1da408a2ff)
1*2b15cb3dSCy Schubert /*
2*2b15cb3dSCy Schubert  * ntp_assert.h - design by contract stuff
3*2b15cb3dSCy Schubert  *
4*2b15cb3dSCy Schubert  * example:
5*2b15cb3dSCy Schubert  *
6*2b15cb3dSCy Schubert  * int foo(char *a) {
7*2b15cb3dSCy Schubert  *	int result;
8*2b15cb3dSCy Schubert  *	int value;
9*2b15cb3dSCy Schubert  *
10*2b15cb3dSCy Schubert  *	REQUIRE(a != NULL);
11*2b15cb3dSCy Schubert  *	...
12*2b15cb3dSCy Schubert  *	bar(&value);
13*2b15cb3dSCy Schubert  *	INSIST(value > 2);
14*2b15cb3dSCy Schubert  *	...
15*2b15cb3dSCy Schubert  *
16*2b15cb3dSCy Schubert  *	ENSURE(result != 12);
17*2b15cb3dSCy Schubert  *	return result;
18*2b15cb3dSCy Schubert  * }
19*2b15cb3dSCy Schubert  *
20*2b15cb3dSCy Schubert  * open question: when would we use INVARIANT()?
21*2b15cb3dSCy Schubert  *
22*2b15cb3dSCy Schubert  * For cases where the overhead for non-debug builds is deemed too high,
23*2b15cb3dSCy Schubert  * use DEBUG_REQUIRE(), DEBUG_INSIST(), DEBUG_ENSURE(), and/or
24*2b15cb3dSCy Schubert  * DEBUG_INVARIANT().
25*2b15cb3dSCy Schubert  */
26*2b15cb3dSCy Schubert 
27*2b15cb3dSCy Schubert #ifndef NTP_ASSERT_H
28*2b15cb3dSCy Schubert #define NTP_ASSERT_H
29*2b15cb3dSCy Schubert 
30*2b15cb3dSCy Schubert # ifdef CALYSTO
31*2b15cb3dSCy Schubert /* see: http://www.domagoj-babic.com/index.php/ResearchProjects/Calysto */
32*2b15cb3dSCy Schubert 
33*2b15cb3dSCy Schubert extern void calysto_assume(unsigned char cnd); /* assume this always holds */
34*2b15cb3dSCy Schubert extern void calysto_assert(unsigned char cnd); /* check whether this holds */
35*2b15cb3dSCy Schubert #define ALWAYS_REQUIRE(x)	calysto_assert(x)
36*2b15cb3dSCy Schubert #define ALWAYS_INSIST(x)	calysto_assume(x) /* DLH calysto_assert()? */
37*2b15cb3dSCy Schubert #define ALWAYS_INVARIANT(x)	calysto_assume(x)
38*2b15cb3dSCy Schubert #define ALWAYS_ENSURE(x)	calysto_assert(x)
39*2b15cb3dSCy Schubert 
40*2b15cb3dSCy Schubert /* # elif defined(__COVERITY__) */
41*2b15cb3dSCy Schubert /*
42*2b15cb3dSCy Schubert  * DH: try letting coverity scan our actual assertion macros, now that
43*2b15cb3dSCy Schubert  * isc_assertioncallback_t is marked __attribute__ __noreturn__.
44*2b15cb3dSCy Schubert  */
45*2b15cb3dSCy Schubert 
46*2b15cb3dSCy Schubert /*
47*2b15cb3dSCy Schubert  * Coverity has special knowledge that assert(x) terminates the process
48*2b15cb3dSCy Schubert  * if x is not true.  Rather than teach it about our assertion macros,
49*2b15cb3dSCy Schubert  * just use the one it knows about for Coverity Prevent scans.  This
50*2b15cb3dSCy Schubert  * means our assertion code (and ISC's) escapes Coverity analysis, but
51*2b15cb3dSCy Schubert  * that seems to be a reasonable trade-off.
52*2b15cb3dSCy Schubert  */
53*2b15cb3dSCy Schubert 
54*2b15cb3dSCy Schubert /*
55*2b15cb3dSCy Schubert #define ALWAYS_REQUIRE(x)	assert(x)
56*2b15cb3dSCy Schubert #define ALWAYS_INSIST(x)	assert(x)
57*2b15cb3dSCy Schubert #define ALWAYS_INVARIANT(x)	assert(x)
58*2b15cb3dSCy Schubert #define ALWAYS_ENSURE(x)	assert(x)
59*2b15cb3dSCy Schubert */
60*2b15cb3dSCy Schubert 
61*2b15cb3dSCy Schubert 
62*2b15cb3dSCy Schubert #elif defined(__FLEXELINT__)
63*2b15cb3dSCy Schubert 
64*2b15cb3dSCy Schubert #include <assert.h>
65*2b15cb3dSCy Schubert 
66*2b15cb3dSCy Schubert #define ALWAYS_REQUIRE(x)	assert(x)
67*2b15cb3dSCy Schubert #define ALWAYS_INSIST(x)	assert(x)
68*2b15cb3dSCy Schubert #define ALWAYS_INVARIANT(x)	assert(x)
69*2b15cb3dSCy Schubert #define ALWAYS_ENSURE(x)	assert(x)
70*2b15cb3dSCy Schubert 
71*2b15cb3dSCy Schubert # else	/* neither Calysto, Coverity or FlexeLint */
72*2b15cb3dSCy Schubert 
73*2b15cb3dSCy Schubert #include "isc/assertions.h"
74*2b15cb3dSCy Schubert 
75*2b15cb3dSCy Schubert #define ALWAYS_REQUIRE(x)	ISC_REQUIRE(x)
76*2b15cb3dSCy Schubert #define ALWAYS_INSIST(x)	ISC_INSIST(x)
77*2b15cb3dSCy Schubert #define ALWAYS_INVARIANT(x)	ISC_INVARIANT(x)
78*2b15cb3dSCy Schubert #define ALWAYS_ENSURE(x)	ISC_ENSURE(x)
79*2b15cb3dSCy Schubert 
80*2b15cb3dSCy Schubert # endif /* neither Coverity nor Calysto */
81*2b15cb3dSCy Schubert 
82*2b15cb3dSCy Schubert #define	REQUIRE(x)		ALWAYS_REQUIRE(x)
83*2b15cb3dSCy Schubert #define	INSIST(x)		ALWAYS_INSIST(x)
84*2b15cb3dSCy Schubert #define	INVARIANT(x)		ALWAYS_INVARIANT(x)
85*2b15cb3dSCy Schubert #define	ENSURE(x)		ALWAYS_ENSURE(x)
86*2b15cb3dSCy Schubert 
87*2b15cb3dSCy Schubert /*
88*2b15cb3dSCy Schubert  * We initially used NTP_REQUIRE() instead of REQUIRE() etc, but that
89*2b15cb3dSCy Schubert  * is unneccesarily verbose, as libisc use of REQUIRE() etc shows.
90*2b15cb3dSCy Schubert  */
91*2b15cb3dSCy Schubert 
92*2b15cb3dSCy Schubert # ifdef DEBUG
93*2b15cb3dSCy Schubert #define	DEBUG_REQUIRE(x)	REQUIRE(x)
94*2b15cb3dSCy Schubert #define	DEBUG_INSIST(x)		INSIST(x)
95*2b15cb3dSCy Schubert #define	DEBUG_INVARIANT(x)	INVARIANT(x)
96*2b15cb3dSCy Schubert #define	DEBUG_ENSURE(x)		ENSURE(x)
97*2b15cb3dSCy Schubert # else
98*2b15cb3dSCy Schubert #define	DEBUG_REQUIRE(x)	do {} while (FALSE)
99*2b15cb3dSCy Schubert #define	DEBUG_INSIST(x)		do {} while (FALSE)
100*2b15cb3dSCy Schubert #define	DEBUG_INVARIANT(x)	do {} while (FALSE)
101*2b15cb3dSCy Schubert #define	DEBUG_ENSURE(x)		do {} while (FALSE)
102*2b15cb3dSCy Schubert # endif
103*2b15cb3dSCy Schubert 
104*2b15cb3dSCy Schubert #endif	/* NTP_ASSERT_H */
105