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