From: Bruno Haible Date: Sat, 28 Oct 2023 16:42:47 +0000 (+0200) Subject: fpe-trapping: Always clear the FE_INVALID exception flag first. X-Git-Tag: v1.0~672 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=ab7f5659b785f1db4192f67e66090a4ab7cd6e94;p=gnulib.git fpe-trapping: Always clear the FE_INVALID exception flag first. * lib/fpe-trapping.h: Include on all platforms. (sigfpe_on_invalid) [AIX, HP-UX, IRIX, Solaris] : Clear the FE_INVALID exception flag first. * modules/fpe-trapping (Depends-on): Add fenv-exceptions-tracking-c99. --- diff --git a/ChangeLog b/ChangeLog index 3af21529c2..a527f14ae8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2023-10-28 Bruno Haible + + fpe-trapping: Always clear the FE_INVALID exception flag first. + * lib/fpe-trapping.h: Include on all platforms. + (sigfpe_on_invalid) [AIX, HP-UX, IRIX, Solaris] : Clear the FE_INVALID + exception flag first. + * modules/fpe-trapping (Depends-on): Add fenv-exceptions-tracking-c99. + 2023-10-28 Bruno Haible fenv-exceptions-tracking-c99: Add tests. diff --git a/lib/fpe-trapping.h b/lib/fpe-trapping.h index 6a63327da9..9040a218ce 100644 --- a/lib/fpe-trapping.h +++ b/lib/fpe-trapping.h @@ -25,11 +25,11 @@ #define HAVE_FPE_TRAPPING 1 +#include + #if HAVE_FEENABLEEXCEPT /* glibc, FreeBSD ≥ 6.0, NetBSD ≥ 7.0, OpenBSD ≥ 5.0, Cygwin ≥ 1.7.8, Android, Haiku. */ -# include - static int sigfpe_on_invalid () { @@ -69,7 +69,7 @@ sigfpe_on_invalid () #endif #if (defined __FreeBSD__ || defined __NetBSD__) && defined __arm__ - /* Work around a bug with FreeBSD 12.2 on arm64 CPUs: + /* Work around a bug with FreeBSD 12.2 on arm CPUs: feenableexcept returns success even if the CPU does not support the request. */ /* Test whether fpscr was actually changed as desired. */ @@ -102,8 +102,17 @@ sigfpe_on_invalid () static int sigfpe_on_invalid () { + /* Clear FE_INVALID exceptions from past operations. */ + feclearexcept (FE_INVALID); + fpsetmask (fpgetmask () | FP_X_INV); + #if defined __arm__ || defined __aarch64__ + /* Test whether the CPU supports the request. */ + if ((fpgetmask () & ~FP_X_INV) == 0) + return -1; + #endif + return 0; } @@ -115,6 +124,9 @@ sigfpe_on_invalid () static int sigfpe_on_invalid () { + /* Clear FE_INVALID exceptions from past operations. */ + feclearexcept (FE_INVALID); + fesettrapenable (fegettrapenable () | FE_INVALID); return 0; @@ -128,6 +140,9 @@ sigfpe_on_invalid () static int sigfpe_on_invalid () { + /* Clear FE_INVALID exceptions from past operations. */ + feclearexcept (FE_INVALID); + /* Enable precise trapping mode. Documentation: */ fp_trap (FP_TRAP_SYNC); diff --git a/modules/fpe-trapping b/modules/fpe-trapping index d8acbe8a27..353e77bdef 100644 --- a/modules/fpe-trapping +++ b/modules/fpe-trapping @@ -10,6 +10,7 @@ m4/musl.m4 Depends-on: extensions +fenv-exceptions-tracking-c99 configure.ac: gl_FPE_TRAPPING