From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1791) id 981E6385840D; Tue, 19 Dec 2023 18:35:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 981E6385840D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1703010924; bh=N7kNrATh4yfSTBIYZH3FcXLqpPzE+eviFux6beYJjew=; h=From:To:Subject:Date:From; b=oBi4nJrdhIzoeEROVyXdirNbDYdmrQsgAOQ83L5BeR+AFEGJt+feIUdK+WbR27jfC 0gQsyRrWt4tHdfkyWoKvvpmlQp0a4AVZtkwoXhjgbx64GgxmsloQMGSk6EzXhztqPk qc8dl9uu33tZbCEtkB6jGNRHyrvm+lMzRlo9ZpXM= MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="utf-8" From: Adhemerval Zanella To: glibc-cvs@sourceware.org Subject: [glibc] powerpc: Do not raise exception traps for fesetexcept/fesetexceptflag (BZ 30988) X-Act-Checkin: glibc X-Git-Author: Adhemerval Zanella X-Git-Refname: refs/heads/master X-Git-Oldrev: f94446c38fb3f4ad26183984c490a9590cd05282 X-Git-Newrev: ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd Message-Id: <20231219183524.981E6385840D@sourceware.org> Date: Tue, 19 Dec 2023 18:35:24 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd commit ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd Author: Adhemerval Zanella Date: Tue Oct 24 08:37:14 2023 -0300 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 Diff: --- math/test-fesetexcept-traps.c | 24 ++++++++++++++++-------- math/test-fexcept-traps.c | 16 +++++++++------- sysdeps/powerpc/fpu/fesetexcept.c | 5 +++++ sysdeps/powerpc/fpu/fsetexcptflg.c | 9 ++++++++- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/math/test-fesetexcept-traps.c b/math/test-fesetexcept-traps.c index 71b6e45b33..7efcd0343a 100644 --- a/math/test-fesetexcept-traps.c +++ b/math/test-fesetexcept-traps.c @@ -39,16 +39,24 @@ do_test (void) return result; } - if (EXCEPTION_SET_FORCES_TRAP) - { - puts ("setting exceptions traps, cannot test on this architecture"); - return 77; - } - /* Verify fesetexcept does not cause exception traps. */ + /* Verify fesetexcept does not cause exception traps. For architectures + where setting the exception might result in traps the function should + return a nonzero value. */ ret = fesetexcept (FE_ALL_EXCEPT); + + _Static_assert (!(EXCEPTION_SET_FORCES_TRAP && !EXCEPTION_TESTS(float)), + "EXCEPTION_SET_FORCES_TRAP only makes sense if the " + "architecture suports exceptions"); + if (ret == 0) - puts ("fesetexcept (FE_ALL_EXCEPT) succeeded"); - else + { + if (EXCEPTION_SET_FORCES_TRAP) + { + puts ("unexpected fesetexcept success"); + result = 1; + } + } + else if (!EXCEPTION_SET_FORCES_TRAP) { puts ("fesetexcept (FE_ALL_EXCEPT) failed"); if (EXCEPTION_TESTS (float)) diff --git a/math/test-fexcept-traps.c b/math/test-fexcept-traps.c index 9701c3c320..998c241058 100644 --- a/math/test-fexcept-traps.c +++ b/math/test-fexcept-traps.c @@ -63,14 +63,16 @@ do_test (void) result = 1; } - if (EXCEPTION_SET_FORCES_TRAP) - { - puts ("setting exceptions traps, cannot test on this architecture"); - return 77; - } - /* The test is that this does not cause exception traps. */ + /* The test is that this does not cause exception traps. For architectures + where setting the exception might result in traps the function should + return a nonzero value. */ ret = fesetexceptflag (&saved, FE_ALL_EXCEPT); - if (ret != 0) + + _Static_assert (!(EXCEPTION_SET_FORCES_TRAP && !EXCEPTION_TESTS(float)), + "EXCEPTION_SET_FORCES_TRAP only makes sense if the " + "architecture suports exceptions"); + + if (ret != 0 && !EXCEPTION_SET_FORCES_TRAP) { puts ("fesetexceptflag failed"); result = 1; diff --git a/sysdeps/powerpc/fpu/fesetexcept.c b/sysdeps/powerpc/fpu/fesetexcept.c index 609a148a95..2850156d3a 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 2b22f913c0..6517e8ea03 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)