aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/config
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2019-01-30 16:04:06 +0100
committerUros Bizjak <uros@gcc.gnu.org>2019-01-30 16:04:06 +0100
commitde0c04f99c561d71a97ad3e89c09027c1815d804 (patch)
treeb76ed6ffe7feae8d614585591f75d89566fc0eb2 /libgfortran/config
parent83a67c0cd7fd11f6ca6a88d2e7db594ef7449454 (diff)
re PR fortran/88678 (Many gfortran.dg/ieee/ieee_X.f90 test cases fail starting with r267465)
PR fortran/88678 * config/fpu-glibc.h (set_fpu_trap_exceptions): Clear stalled exception flags before changing trap mode. Optimize to call feenableexcept and fedisableexcept only once. From-SVN: r268392
Diffstat (limited to 'libgfortran/config')
-rw-r--r--libgfortran/config/fpu-glibc.h32
1 files changed, 20 insertions, 12 deletions
diff --git a/libgfortran/config/fpu-glibc.h b/libgfortran/config/fpu-glibc.h
index c24bb6cbcd9..9abdfd95ee3 100644
--- a/libgfortran/config/fpu-glibc.h
+++ b/libgfortran/config/fpu-glibc.h
@@ -39,48 +39,56 @@ _Static_assert (sizeof(fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE,
void set_fpu_trap_exceptions (int trap, int notrap)
{
+ int mode_set = 0, mode_clr = 0;
+
#ifdef FE_INVALID
if (trap & GFC_FPE_INVALID)
- feenableexcept (FE_INVALID);
+ mode_set |= FE_INVALID;
if (notrap & GFC_FPE_INVALID)
- fedisableexcept (FE_INVALID);
+ mode_clr |= FE_INVALID;
#endif
/* Some glibc targets (like alpha) have FE_DENORMAL, but not many. */
#ifdef FE_DENORMAL
if (trap & GFC_FPE_DENORMAL)
- feenableexcept (FE_DENORMAL);
+ mode_set |= FE_DENORMAL;
if (notrap & GFC_FPE_DENORMAL)
- fedisableexcept (FE_DENORMAL);
+ mode_clr |= FE_DENORMAL;
#endif
#ifdef FE_DIVBYZERO
if (trap & GFC_FPE_ZERO)
- feenableexcept (FE_DIVBYZERO);
+ mode_set |= FE_DIVBYZERO;
if (notrap & GFC_FPE_ZERO)
- fedisableexcept (FE_DIVBYZERO);
+ mode_clr |= FE_DIVBYZERO;
#endif
#ifdef FE_OVERFLOW
if (trap & GFC_FPE_OVERFLOW)
- feenableexcept (FE_OVERFLOW);
+ mode_set |= FE_OVERFLOW;
if (notrap & GFC_FPE_OVERFLOW)
- fedisableexcept (FE_OVERFLOW);
+ mode_clr |= FE_OVERFLOW;
#endif
#ifdef FE_UNDERFLOW
if (trap & GFC_FPE_UNDERFLOW)
- feenableexcept (FE_UNDERFLOW);
+ mode_set |= FE_UNDERFLOW;
if (notrap & GFC_FPE_UNDERFLOW)
- fedisableexcept (FE_UNDERFLOW);
+ mode_clr |= FE_UNDERFLOW;
#endif
#ifdef FE_INEXACT
if (trap & GFC_FPE_INEXACT)
- feenableexcept (FE_INEXACT);
+ mode_set |= FE_INEXACT;
if (notrap & GFC_FPE_INEXACT)
- fedisableexcept (FE_INEXACT);
+ mode_clr |= FE_INEXACT;
#endif
+
+ /* Clear stalled exception flags. */
+ feclearexcept (FE_ALL_EXCEPT);
+
+ feenableexcept (mode_set);
+ fedisableexcept (mode_clr);
}