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
35extern void calysto_assume(unsigned char cnd); /* assume this always holds */
36extern 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