mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
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>
This commit is contained in:
parent
f94446c38f
commit
ecb1e7220d
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user