From de0c04f99c561d71a97ad3e89c09027c1815d804 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Wed, 30 Jan 2019 16:04:06 +0100 Subject: [PATCH] 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 --- libgfortran/ChangeLog | 7 +++++++ libgfortran/config/fpu-glibc.h | 32 ++++++++++++++++++++------------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 2a604a5959c..87fc2d6a38c 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,10 @@ +2019-01-30 Uroš Bizjak + + 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. + 2019-01-28 Sebastian Huber * io/async.c (init_adv_cond): Use __GTHREAD_COND_INIT_FUNCTION(). 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); } -- 2.30.2