From: uros Date: Wed, 30 Jan 2019 15:04:06 +0000 (+0000) Subject: PR fortran/88678 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99ec6287ef652dc28abb7b0546707eb0cedc497c;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@268392 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 2a604a5959ca..87fc2d6a38ca 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 c24bb6cbcd92..9abdfd95ee3b 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); }