diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-10-24 08:37:14 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-12-19 15:12:34 -0300 |
commit | ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd (patch) | |
tree | 5e38bda17e720b93e0a50273c75c3acb27efd8f8 /math | |
parent | f94446c38fb3f4ad26183984c490a9590cd05282 (diff) | |
download | glibc-ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd.tar.gz glibc-ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd.tar.xz glibc-ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd.zip |
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 'math')
-rw-r--r-- | math/test-fesetexcept-traps.c | 24 | ||||
-rw-r--r-- | math/test-fexcept-traps.c | 16 |
2 files changed, 25 insertions, 15 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; |