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