re PR fortran/88678 (Many gfortran.dg/ieee/ieee_X.f90 test cases fail starting with...
authorUros Bizjak <ubizjak@gmail.com>
Wed, 30 Jan 2019 15:04:06 +0000 (16:04 +0100)
committerUros Bizjak <uros@gcc.gnu.org>
Wed, 30 Jan 2019 15:04:06 +0000 (16:04 +0100)
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
libgfortran/config/fpu-glibc.h

index 2a604a5959ca17f6669a5a7a42d4bed09b2dc01b..87fc2d6a38caa0b904b35bfa7753ebcd197ff591 100644 (file)
@@ -1,3 +1,10 @@
+2019-01-30  Uroš Bizjak  <ubizjak@gmail.com>
+
+       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  <sebastian.huber@embedded-brains.de>
 
        * io/async.c (init_adv_cond): Use __GTHREAD_COND_INIT_FUNCTION().
index c24bb6cbcd92ee26d39c891372262f7cade5b474..9abdfd95ee3bd62fd6f245e035b7a8b8e09bdf47 100644 (file)
@@ -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);
 }