[Bug fortran/52413] Incorrect behavior of FRACTION when applied to a constant

dominiq at lps dot ens.fr gcc-bugzilla@gcc.gnu.org
Sun Jun 23 15:35:00 GMT 2013


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52413

--- Comment #10 from Dominique d'Humieres <dominiq at lps dot ens.fr> ---
Here is the patch I plan to package and submit:

--- ../_clean/gcc/fortran/simplify.c    2013-06-08 21:50:33.000000000 +0200
+++ gcc/fortran/simplify.c    2013-06-23 17:19:55.000000000 +0200
@@ -2342,16 +2342,26 @@ gfc_expr *
 gfc_simplify_fraction (gfc_expr *x)
 {
   gfc_expr *result;
+
+#if MPFR_VERSION < MPFR_VERSION_NUM(3,1,0)
   mpfr_t absv, exp, pow2;
+#else
+  mpfr_exp_t e;
+#endif

   if (x->expr_type != EXPR_CONSTANT)
     return NULL;

   result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);

+#if MPFR_VERSION < MPFR_VERSION_NUM(3,1,0)
+
+  /* MPFR versions before 3.1.0 do not include mpfr_frexp.  
+     TODO: remove the kludge when MPFR 3.1.0 or newer will be required */
+
   if (mpfr_sgn (x->value.real) == 0)
     {
-      mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
+      mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
       return result;
     }

@@ -2368,10 +2378,16 @@ gfc_simplify_fraction (gfc_expr *x)

   mpfr_ui_pow (pow2, 2, exp, GFC_RND_MODE);

-  mpfr_div (result->value.real, absv, pow2, GFC_RND_MODE);
+  mpfr_div (result->value.real, x->value.real, pow2, GFC_RND_MODE);

   mpfr_clears (exp, absv, pow2, NULL);

+#else
+
+  mpfr_frexp (&e, result->value.real, x->value.real, GFC_RND_MODE);
+
+#endif
+
   return range_check (result, "FRACTION");
 }

--- ../_clean/gcc/testsuite/gfortran.dg/fraction.f90    1970-01-01
01:00:00.000000000 +0100
+++ gcc/testsuite/gfortran.dg/fraction.f90    2013-06-23 17:25:09.000000000
+0200
@@ -0,0 +1,16 @@
+! { dg-do run }
+! Test for pr52413
+
+program test_frac
+
+  character(len=26) :: buf
+  real :: y
+  y=fraction (-2.0) 
+  write (buf, *) y
+  if (buf(1:10) /= " -0.500000") call abort ()
+  write (buf, *) fraction (-0.0)
+  if (buf(1:11) /= "  -0.000000") call abort ()
+  write (buf, *) fraction (-2.0_8)
+  if (buf(1:18) /= " -0.50000000000000") call abort ()
+
+end program test_frac

Any comment?

Since the PR is about wrong code, I think it qualifies for some backport with
the patch in comment #8. Should I do the tests or will the backport rejected?



More information about the Gcc-bugs mailing list