Home | History | Annotate | Line # | Download | only in include
      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