summaryrefslogtreecommitdiff
path: root/src/fenv/_fenv.h
blob: b35ec05049a4823cfbf509e703fd9798d7696c8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <fenv.h>
#include "_safety.h"

struct __fenv_t {
	int flags;
};

struct __fexcept_t {
	int mask;
	int set;
};

extern struct __fenv_h {
	struct __fexcept_t *fexcept;
	size_t nfexcept;
	struct __fenv_t *fenv;
	size_t nfenv;
} __fenv_h;

#ifdef NDEBUG
#define ASSERT_VALID_EXCEPTION_MASK(_n) (void)(_n)
#define ASSERT_PREV_FEXCEPT(_f, _e) (void)(_f)
#define ASSERT_PREV_FENV(_f) (void)(_f)
#else
#define ASSERT_VALID_EXCEPTION_MASK(_n) do { \
	if (((_n) & ~(FE_ALL_EXCEPT)) != 0) { \
		UNDEFINED("In call to %s(): exception mask 0x(%jx) is not valid", __func__, (uintmax_t)(_n)); \
	} \
} while (0)

#define ASSERT_PREV_FEXCEPT(__f, __e) do { \
        if (!(__f->__impl >= __fenv_h.fexcept && __f->__impl <= __fenv_h.fexcept + __fenv_h.nfexcept)) { \
		UNDEFINED("In call to %s(): %s must be previously set by calling fegetexceptflag()", __func__, #__f); \
	} \
	if ((__f->__impl->mask & (__e)) != (__e)) { \
		UNDEFINED("In call to %s(): Attempting to set flags not specified by previous call to fegetexceptflag()", __func__); \
	} \
} while (0)

#define ASSERT_PREV_FENV(__f) do { \
        if (!(__f == FE_DFL_ENV) || (__f->__impl >= __fenv_h.fenv && __f->__impl <= __fenv_h.fenv + __fenv_h.nfenv)) { \
		UNDEFINED("In call to %s(): %s must be previously set by calling fegetenv() or feholdexcept()", __func__, #__f); \
	} \
} while (0)
#endif