summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2024-06-07 14:05:47 -0400
committerJakob Kaivo <jkk@ung.org>2024-06-07 14:05:47 -0400
commitc195cb021ead7de765a0b37f5ab793802be46731 (patch)
tree9ce55bbef9c4e3447051541782f340417e78d090
parentee65289f3863fe3ed581dbf035fd77a4b6fba252 (diff)
track valid exception flags when calling fegetexceptflag() and check when calling fesetexceptflag()
-rw-r--r--src/fenv/_fenv.h22
-rw-r--r--src/fenv/fegetexceptflag.c10
-rw-r--r--src/fenv/fesetexceptflag.c4
3 files changed, 28 insertions, 8 deletions
diff --git a/src/fenv/_fenv.h b/src/fenv/_fenv.h
index debfc2ad..b35ec050 100644
--- a/src/fenv/_fenv.h
+++ b/src/fenv/_fenv.h
@@ -5,9 +5,14 @@ struct __fenv_t {
int flags;
};
+struct __fexcept_t {
+ int mask;
+ int set;
+};
+
extern struct __fenv_h {
- fexcept_t *valid_fexcept;
- size_t nvalid_fexcept;
+ struct __fexcept_t *fexcept;
+ size_t nfexcept;
struct __fenv_t *fenv;
size_t nfenv;
} __fenv_h;
@@ -23,10 +28,17 @@ extern struct __fenv_h {
} \
} while (0)
-/* TODO!!! */
-#define ASSERT_PREV_FEXCEPT(_f, _e) (void)(_f)
+#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 (!(envp == FE_DFL_ENV) || (envp->__impl >= __fenv_h.fenv && envp->__impl <= __fenv_h.fenv + __fenv_h.nfenv)) { \
+ 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)
diff --git a/src/fenv/fegetexceptflag.c b/src/fenv/fegetexceptflag.c
index 921dc1b8..ef8517f9 100644
--- a/src/fenv/fegetexceptflag.c
+++ b/src/fenv/fegetexceptflag.c
@@ -5,7 +5,15 @@ int fegetexceptflag(fexcept_t *flagp, int excepts)
{
SIGNAL_SAFE(0);
ASSERT_VALID_EXCEPTION_MASK(excepts);
- (void)flagp; (void)excepts;
+ if (!(flagp->__impl >= __fenv_h.fexcept && flagp->__impl <= __fenv_h.fexcept + __fenv_h.nfexcept)) {
+ struct __fexcept_t *tmp = realloc(__fenv_h.fexcept, sizeof(*__fenv_h.fexcept) * (__fenv_h.nfexcept + 1));
+ if (tmp == NULL) {
+ abort();
+ }
+ __fenv_h.fexcept = tmp;
+ flagp->__impl = &(__fenv_h.fexcept[__fenv_h.nfexcept++]);
+ }
+ flagp->__impl->mask = excepts;
return 0;
}
diff --git a/src/fenv/fesetexceptflag.c b/src/fenv/fesetexceptflag.c
index a68903f2..4c50a76d 100644
--- a/src/fenv/fesetexceptflag.c
+++ b/src/fenv/fesetexceptflag.c
@@ -4,9 +4,9 @@
int fesetexceptflag(const fexcept_t *flagp, int excepts)
{
SIGNAL_SAFE(0);
- ASSERT_PREV_FEXCEPT(flagp, excepts);
ASSERT_VALID_EXCEPTION_MASK(excepts);
- (void)flagp; (void)excepts;
+ ASSERT_PREV_FEXCEPT(flagp, excepts);
+ flagp->__impl->set |= excepts;
return 0;
}