downloaded from https://gforge.inria.fr/scm/viewvc.php/mpfr/misc/www/mpfr-3.1.4/allpatches?revision=10393&view=co
on June 3rd 2016 (last change: 2016-06-01)
diff -Naurd mpfr-3.1.4-a/PATCHES mpfr-3.1.4-b/PATCHES
--- mpfr-3.1.4-a/PATCHES	2016-04-13 21:22:23.720604013 +0000
+++ mpfr-3.1.4-b/PATCHES	2016-04-13 21:22:23.744603677 +0000
@@ -0,0 +1 @@
+unix-check
diff -Naurd mpfr-3.1.4-a/VERSION mpfr-3.1.4-b/VERSION
--- mpfr-3.1.4-a/VERSION	2016-03-06 11:33:04.000000000 +0000
+++ mpfr-3.1.4-b/VERSION	2016-04-13 21:22:23.744603677 +0000
@@ -1 +1 @@
-3.1.4
+3.1.4-p1
diff -Naurd mpfr-3.1.4-a/src/mpfr-impl.h mpfr-3.1.4-b/src/mpfr-impl.h
--- mpfr-3.1.4-a/src/mpfr-impl.h	2016-03-06 11:33:04.000000000 +0000
+++ mpfr-3.1.4-b/src/mpfr-impl.h	2016-04-13 21:22:23.736603789 +0000
@@ -252,19 +252,6 @@
 # define MPFR_WIN_THREAD_SAFE_DLL 1
 #endif
 
-/* Detect some possible inconsistencies under Unix. */
-#if defined(__unix__)
-# if defined(_WIN32)
-#  error "Both __unix__ and _WIN32 are defined"
-# endif
-# if __GMP_LIBGMP_DLL
-#  error "__unix__ is defined and __GMP_LIBGMP_DLL is true"
-# endif
-# if defined(MPFR_WIN_THREAD_SAFE_DLL)
-#  error "Both __unix__ and MPFR_WIN_THREAD_SAFE_DLL are defined"
-# endif
-#endif
-
 #if defined(__MPFR_WITHIN_MPFR) || !defined(MPFR_WIN_THREAD_SAFE_DLL)
 extern MPFR_THREAD_ATTR unsigned int __gmpfr_flags;
 extern MPFR_THREAD_ATTR mpfr_exp_t   __gmpfr_emin;
diff -Naurd mpfr-3.1.4-a/src/mpfr.h mpfr-3.1.4-b/src/mpfr.h
--- mpfr-3.1.4-a/src/mpfr.h	2016-03-06 11:33:04.000000000 +0000
+++ mpfr-3.1.4-b/src/mpfr.h	2016-04-13 21:22:23.744603677 +0000
@@ -27,7 +27,7 @@
 #define MPFR_VERSION_MAJOR 3
 #define MPFR_VERSION_MINOR 1
 #define MPFR_VERSION_PATCHLEVEL 4
-#define MPFR_VERSION_STRING "3.1.4"
+#define MPFR_VERSION_STRING "3.1.4-p1"
 
 /* Macros dealing with MPFR VERSION */
 #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
diff -Naurd mpfr-3.1.4-a/src/version.c mpfr-3.1.4-b/src/version.c
--- mpfr-3.1.4-a/src/version.c	2016-03-06 11:33:05.000000000 +0000
+++ mpfr-3.1.4-b/src/version.c	2016-04-13 21:22:23.744603677 +0000
@@ -25,5 +25,5 @@
 const char *
 mpfr_get_version (void)
 {
-  return "3.1.4";
+  return "3.1.4-p1";
 }
diff -Naurd mpfr-3.1.4-a/PATCHES mpfr-3.1.4-b/PATCHES
--- mpfr-3.1.4-a/PATCHES	2016-05-22 19:59:43.838399677 +0000
+++ mpfr-3.1.4-b/PATCHES	2016-05-22 19:59:43.866399168 +0000
@@ -0,0 +1 @@
+add-sub-ui-flags
diff -Naurd mpfr-3.1.4-a/VERSION mpfr-3.1.4-b/VERSION
--- mpfr-3.1.4-a/VERSION	2016-04-13 21:22:23.744603677 +0000
+++ mpfr-3.1.4-b/VERSION	2016-05-22 19:59:43.866399168 +0000
@@ -1 +1 @@
-3.1.4-p1
+3.1.4-p2
diff -Naurd mpfr-3.1.4-a/src/add_ui.c mpfr-3.1.4-b/src/add_ui.c
--- mpfr-3.1.4-a/src/add_ui.c	2016-03-06 11:33:04.000000000 +0000
+++ mpfr-3.1.4-b/src/add_ui.c	2016-05-22 19:59:43.854399385 +0000
@@ -49,6 +49,7 @@
       MPFR_SAVE_EXPO_MARK (expo);
       MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
       inex = mpfr_add(y, x, uu, rnd_mode);
+      MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
       MPFR_SAVE_EXPO_FREE (expo);
       return mpfr_check_range(y, inex, rnd_mode);
     }
diff -Naurd mpfr-3.1.4-a/src/mpfr.h mpfr-3.1.4-b/src/mpfr.h
--- mpfr-3.1.4-a/src/mpfr.h	2016-04-13 21:22:23.744603677 +0000
+++ mpfr-3.1.4-b/src/mpfr.h	2016-05-22 19:59:43.862399241 +0000
@@ -27,7 +27,7 @@
 #define MPFR_VERSION_MAJOR 3
 #define MPFR_VERSION_MINOR 1
 #define MPFR_VERSION_PATCHLEVEL 4
-#define MPFR_VERSION_STRING "3.1.4-p1"
+#define MPFR_VERSION_STRING "3.1.4-p2"
 
 /* Macros dealing with MPFR VERSION */
 #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
diff -Naurd mpfr-3.1.4-a/src/sub_ui.c mpfr-3.1.4-b/src/sub_ui.c
--- mpfr-3.1.4-a/src/sub_ui.c	2016-03-06 11:33:05.000000000 +0000
+++ mpfr-3.1.4-b/src/sub_ui.c	2016-05-22 19:59:43.854399385 +0000
@@ -52,6 +52,7 @@
       MPFR_SAVE_EXPO_MARK (expo);
       MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt);
       inex = mpfr_sub (y, x, uu, rnd_mode);
+      MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
       MPFR_SAVE_EXPO_FREE (expo);
       return mpfr_check_range (y, inex, rnd_mode);
     }
diff -Naurd mpfr-3.1.4-a/src/version.c mpfr-3.1.4-b/src/version.c
--- mpfr-3.1.4-a/src/version.c	2016-04-13 21:22:23.744603677 +0000
+++ mpfr-3.1.4-b/src/version.c	2016-05-22 19:59:43.866399168 +0000
@@ -25,5 +25,5 @@
 const char *
 mpfr_get_version (void)
 {
-  return "3.1.4-p1";
+  return "3.1.4-p2";
 }
diff -Naurd mpfr-3.1.4-a/tests/tadd_ui.c mpfr-3.1.4-b/tests/tadd_ui.c
--- mpfr-3.1.4-a/tests/tadd_ui.c	2016-03-06 11:33:03.000000000 +0000
+++ mpfr-3.1.4-b/tests/tadd_ui.c	2016-05-22 19:59:43.854399385 +0000
@@ -69,7 +69,9 @@
 
   /* nan + 2394875 == nan */
   mpfr_set_nan (x);
+  mpfr_clear_nanflag ();
   mpfr_add_ui (y, x, 2394875L, MPFR_RNDN);
+  MPFR_ASSERTN (mpfr_nanflag_p ());
   MPFR_ASSERTN (mpfr_nan_p (y));
 
   /* +inf + 2394875 == +inf */
diff -Naurd mpfr-3.1.4-a/tests/tsub_ui.c mpfr-3.1.4-b/tests/tsub_ui.c
--- mpfr-3.1.4-a/tests/tsub_ui.c	2016-03-06 11:33:03.000000000 +0000
+++ mpfr-3.1.4-b/tests/tsub_ui.c	2016-05-22 19:59:43.854399385 +0000
@@ -96,7 +96,9 @@
 
   /* nan - 1 == nan */
   mpfr_set_nan (x);
+  mpfr_clear_nanflag ();
   mpfr_sub_ui (y, x, 1L, MPFR_RNDN);
+  MPFR_ASSERTN (mpfr_nanflag_p ());
   MPFR_ASSERTN (mpfr_nan_p (y));
 
   /* +inf - 1 == +inf */
diff -Naurd mpfr-3.1.4-a/PATCHES mpfr-3.1.4-b/PATCHES
--- mpfr-3.1.4-a/PATCHES	2016-06-01 13:00:30.748711490 +0000
+++ mpfr-3.1.4-b/PATCHES	2016-06-01 13:00:30.772711162 +0000
@@ -0,0 +1 @@
+sub1-overflow
diff -Naurd mpfr-3.1.4-a/VERSION mpfr-3.1.4-b/VERSION
--- mpfr-3.1.4-a/VERSION	2016-05-22 19:59:43.866399168 +0000
+++ mpfr-3.1.4-b/VERSION	2016-06-01 13:00:30.772711162 +0000
@@ -1 +1 @@
-3.1.4-p2
+3.1.4-p3
diff -Naurd mpfr-3.1.4-a/src/mpfr.h mpfr-3.1.4-b/src/mpfr.h
--- mpfr-3.1.4-a/src/mpfr.h	2016-05-22 19:59:43.862399241 +0000
+++ mpfr-3.1.4-b/src/mpfr.h	2016-06-01 13:00:30.772711162 +0000
@@ -27,7 +27,7 @@
 #define MPFR_VERSION_MAJOR 3
 #define MPFR_VERSION_MINOR 1
 #define MPFR_VERSION_PATCHLEVEL 4
-#define MPFR_VERSION_STRING "3.1.4-p2"
+#define MPFR_VERSION_STRING "3.1.4-p3"
 
 /* Macros dealing with MPFR VERSION */
 #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
diff -Naurd mpfr-3.1.4-a/src/sub1.c mpfr-3.1.4-b/src/sub1.c
--- mpfr-3.1.4-a/src/sub1.c	2016-03-06 11:33:05.000000000 +0000
+++ mpfr-3.1.4-b/src/sub1.c	2016-06-01 13:00:30.760711326 +0000
@@ -96,16 +96,15 @@
       /* A = S*ABS(B) +/- ulp(a) */
       MPFR_SET_EXP (a, MPFR_GET_EXP (b));
       MPFR_RNDRAW_EVEN (inexact, a, MPFR_MANT (b), MPFR_PREC (b),
-                        rnd_mode, MPFR_SIGN (a),
-                        if (MPFR_UNLIKELY ( ++MPFR_EXP (a) > __gmpfr_emax))
-                        inexact = mpfr_overflow (a, rnd_mode, MPFR_SIGN (a)));
-      /* inexact = mpfr_set4 (a, b, rnd_mode, MPFR_SIGN (a));  */
+                        rnd_mode, MPFR_SIGN (a), ++ MPFR_EXP (a));
       if (inexact == 0)
         {
           /* a = b (Exact)
              But we know it isn't (Since we have to remove `c')
              So if we round to Zero, we have to remove one ulp.
              Otherwise the result is correctly rounded. */
+          /* An overflow is not possible. */
+          MPFR_ASSERTD (MPFR_EXP (a) <= __gmpfr_emax);
           if (MPFR_IS_LIKE_RNDZ (rnd_mode, MPFR_IS_NEG (a)))
             {
               mpfr_nexttozero (a);
@@ -136,9 +135,14 @@
              i.e. inexact= MPFR_EVEN_INEX */
           if (MPFR_UNLIKELY (inexact == MPFR_EVEN_INEX*MPFR_INT_SIGN (a)))
             {
-              mpfr_nexttozero (a);
+              if (MPFR_UNLIKELY (MPFR_EXP (a) > __gmpfr_emax))
+                mpfr_setmax (a, __gmpfr_emax);
+              else
+                mpfr_nexttozero (a);
               inexact = -MPFR_INT_SIGN (a);
             }
+          else if (MPFR_UNLIKELY (MPFR_EXP (a) > __gmpfr_emax))
+            inexact = mpfr_overflow (a, rnd_mode, MPFR_SIGN (a));
           MPFR_RET (inexact);
         }
     }
diff -Naurd mpfr-3.1.4-a/src/version.c mpfr-3.1.4-b/src/version.c
--- mpfr-3.1.4-a/src/version.c	2016-05-22 19:59:43.866399168 +0000
+++ mpfr-3.1.4-b/src/version.c	2016-06-01 13:00:30.772711162 +0000
@@ -25,5 +25,5 @@
 const char *
 mpfr_get_version (void)
 {
-  return "3.1.4-p2";
+  return "3.1.4-p3";
 }
diff -Naurd mpfr-3.1.4-a/tests/tsub.c mpfr-3.1.4-b/tests/tsub.c
--- mpfr-3.1.4-a/tests/tsub.c	2016-03-06 11:33:03.000000000 +0000
+++ mpfr-3.1.4-b/tests/tsub.c	2016-06-01 13:00:30.760711326 +0000
@@ -630,6 +630,135 @@
     }
 }
 
+static void
+check_max_almosteven (void)
+{
+  mpfr_exp_t old_emin, old_emax;
+  mpfr_exp_t emin[2] = { MPFR_EMIN_MIN, -1000 };
+  mpfr_exp_t emax[2] = { MPFR_EMAX_MAX, 1000 };
+  int i;
+
+  old_emin = mpfr_get_emin ();
+  old_emax = mpfr_get_emax ();
+
+  for (i = 0; i < 2; i++)
+    {
+      mpfr_t a1, a2, b, c;
+      mpfr_prec_t p;
+      int neg, j, rnd;
+
+      set_emin (emin[i]);
+      set_emax (emax[i]);
+
+      p = MPFR_PREC_MIN + randlimb () % 70;
+      mpfr_init2 (a1, p);
+      mpfr_init2 (a2, p);
+      mpfr_init2 (b, p+1);
+      mpfr_init2 (c, MPFR_PREC_MIN);
+
+      mpfr_setmax (b, 0);
+      mpfr_set_ui (c, 1, MPFR_RNDN);
+
+      for (neg = 0; neg < 2; neg++)
+        {
+          for (j = 1; j >= 0; j--)
+            {
+              mpfr_set_exp (b, __gmpfr_emax - j);
+              RND_LOOP (rnd)
+                {
+                  unsigned int flags1, flags2;
+                  int inex1, inex2;
+
+                  flags1 = MPFR_FLAGS_INEXACT;
+                  if (rnd == MPFR_RNDN || MPFR_IS_LIKE_RNDZ (rnd, neg))
+                    {
+                      inex1 = neg ? 1 : -1;
+                      mpfr_setmax (a1, __gmpfr_emax - j);
+                    }
+                  else
+                    {
+                      inex1 = neg ? -1 : 1;
+                      if (j == 0)
+                        {
+                          flags1 |= MPFR_FLAGS_OVERFLOW;
+                          mpfr_set_inf (a1, 1);
+                        }
+                      else
+                        {
+                          mpfr_setmin (a1, __gmpfr_emax);
+                        }
+                    }
+                  MPFR_SET_SIGN (a1, neg ? -1 : 1);
+
+                  mpfr_clear_flags ();
+                  inex2 = mpfr_sub (a2, b, c, (mpfr_rnd_t) rnd);
+                  flags2 = __gmpfr_flags;
+
+                  if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
+                         mpfr_equal_p (a1, a2)))
+                    {
+                      printf ("Error 1 in check_max_almosteven for %s,"
+                              " i = %d, j = %d, neg = %d\n",
+                              mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
+                              i, j, neg);
+                      printf ("     b = ");
+                      mpfr_dump (b);
+                      printf ("Expected ");
+                      mpfr_dump (a1);
+                      printf ("  with inex = %d, flags =", inex1);
+                      flags_out (flags1);
+                      printf ("Got      ");
+                      mpfr_dump (a2);
+                      printf ("  with inex = %d, flags =", inex2);
+                      flags_out (flags2);
+                      exit (1);
+                    }
+
+                  if (i == 0)
+                    break;
+
+                  mpfr_clear_flags ();
+                  set_emin (MPFR_EMIN_MIN);
+                  set_emax (MPFR_EMAX_MAX);
+                  inex2 = mpfr_sub (a2, b, c, (mpfr_rnd_t) rnd);
+                  set_emin (emin[i]);
+                  set_emax (emax[i]);
+                  inex2 = mpfr_check_range (a2, inex2, (mpfr_rnd_t) rnd);
+                  flags2 = __gmpfr_flags;
+
+                  if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
+                         mpfr_equal_p (a1, a2)))
+                    {
+                      printf ("Error 2 in check_max_almosteven for %s,"
+                              " i = %d, j = %d, neg = %d\n",
+                              mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
+                              i, j, neg);
+                      printf ("     b = ");
+                      mpfr_dump (b);
+                      printf ("Expected ");
+                      mpfr_dump (a1);
+                      printf ("  with inex = %d, flags =", inex1);
+                      flags_out (flags1);
+                      printf ("Got      ");
+                      mpfr_dump (a2);
+                      printf ("  with inex = %d, flags =", inex2);
+                      flags_out (flags2);
+                      exit (1);
+                    }
+                }
+            }  /* j */
+
+          mpfr_neg (b, b, MPFR_RNDN);
+          mpfr_neg (c, c, MPFR_RNDN);
+        }  /* neg */
+
+      mpfr_clears (a1, a2, b, c, (mpfr_ptr) 0);
+    }  /* i */
+
+  set_emin (old_emin);
+  set_emax (old_emax);
+}
+
 #define TEST_FUNCTION test_sub
 #define TWO_ARGS
 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
@@ -647,6 +776,7 @@
   check_rounding ();
   check_diverse ();
   check_inexact ();
+  check_max_almosteven ();
   bug_ddefour ();
   for (p=2; p<200; p++)
     for (i=0; i<50; i++)
