aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/powerpc/fpu
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-10-24 08:37:14 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-12-19 15:12:34 -0300
commitecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd (patch)
tree5e38bda17e720b93e0a50273c75c3acb27efd8f8 /sysdeps/powerpc/fpu
parentf94446c38fb3f4ad26183984c490a9590cd05282 (diff)
downloadglibc-ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd.zip
glibc-ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd.tar.gz
glibc-ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd.tar.bz2
powerpc: Do not raise exception traps for fesetexcept/fesetexceptflag (BZ 30988)
According to ISO C23 (7.6.4.4), fesetexcept is supposed to set floating-point exception flags without raising a trap (unlike feraiseexcept, which is supposed to raise a trap if feenableexcept was called with the appropriate argument). This is a side-effect of how we implement the GNU extension feenableexcept, where feenableexcept/fesetenv/fesetmode/feupdateenv might issue prctl (PR_SET_FPEXC, PR_FP_EXC_PRECISE) depending of the argument. And on PR_FP_EXC_PRECISE, setting a floating-point exception flag triggers a trap. To make the both functions follow the C23, fesetexcept and fesetexceptflag now fail if the argument may trigger a trap. The math tests now check for an value different than 0, instead of bail out as unsupported for EXCEPTION_SET_FORCES_TRAP. Checked on powerpc64le-linux-gnu. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'sysdeps/powerpc/fpu')
-rw-r--r--sysdeps/powerpc/fpu/fesetexcept.c5
-rw-r--r--sysdeps/powerpc/fpu/fsetexcptflg.c9
2 files changed, 13 insertions, 1 deletions
diff --git a/sysdeps/powerpc/fpu/fesetexcept.c b/sysdeps/powerpc/fpu/fesetexcept.c
index 609a148..2850156 100644
--- a/sysdeps/powerpc/fpu/fesetexcept.c
+++ b/sysdeps/powerpc/fpu/fesetexcept.c
@@ -31,6 +31,11 @@ fesetexcept (int excepts)
& FE_INVALID_SOFTWARE));
if (n.l != u.l)
{
+ if (n.l & fenv_exceptions_to_reg (excepts))
+ /* Setting the exception flags may trigger a trap. ISO C 23 § 7.6.4.4
+ does not allow it. */
+ return -1;
+
fesetenv_register (n.fenv);
/* Deal with FE_INVALID_SOFTWARE not being implemented on some chips. */
diff --git a/sysdeps/powerpc/fpu/fsetexcptflg.c b/sysdeps/powerpc/fpu/fsetexcptflg.c
index 2b22f91..6517e8e 100644
--- a/sysdeps/powerpc/fpu/fsetexcptflg.c
+++ b/sysdeps/powerpc/fpu/fsetexcptflg.c
@@ -44,7 +44,14 @@ __fesetexceptflag (const fexcept_t *flagp, int excepts)
This may cause floating-point exceptions if the restored state
requests it. */
if (n.l != u.l)
- fesetenv_register (n.fenv);
+ {
+ if (n.l & fenv_exceptions_to_reg (excepts))
+ /* Setting the exception flags may trigger a trap. ISO C 23 § 7.6.4.4
+ does not allow it. */
+ return -1;
+
+ fesetenv_register (n.fenv);
+ }
/* Deal with FE_INVALID_SOFTWARE not being implemented on some chips. */
if (flag & FE_INVALID)