This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[Patch, Fortran] PR52413 - Incorrect behavior of FRACTION when applied to a constant
- From: dominiq at lps dot ens dot fr (Dominique Dhumieres)
- To: fortran at gcc dot gnu dot org
- Cc: fxcoudert at gcc dot gnu dot org, sgk at troutmask dot apl dot washington dot edu, gcc-patches at gcc dot gnu dot org
- Date: Sun, 23 Jun 2013 23:43:57 +0200
- Subject: [Patch, Fortran] PR52413 - Incorrect behavior of FRACTION when applied to a constant
This patch packages the Steven G. Kargl's patch when MPFR 3.1.0 or newer
is available and fixes the original code for older versions using the
FX Coudert's machinery (see PR for details).
Tested on powerpc-apple-darwin9 and x86_64-apple-darwin10 without
regression.
OK for the trunk? If yes, could someone commit it for me?
Since this is a wrong-code issue, I think the light version of the patch
should be applied to 4.7 and 4.8. If this is accepted I'll do the testing
and the packaging.
Dominique
2013-06-23 Steven G. Kargl <sgk@troutmask.apl.washington.edu>
Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Dominique d'Humieres <dominiq@lps.ens.fr>
PR fortran/52413
* simplify.c: Fix the sign of negative values in gfc_simplify_fraction.
2013-06-23 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
Dominique d'Humieres <dominiq@lps.ens.fr>
PR fortran/52413
* gfortran.dg/fraction.f90: New.
--- ../_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 22:06:00.000000000 +0200
@@ -0,0 +1,15 @@
+! { dg-do run }
+!
+! Test for pr52413
+!
+
+program test_frac
+
+ real :: y
+ y=fraction (-2.0)
+ if (fraction (-2.0) /= -0.5) call abort ()
+ if (fraction (-0.0) /= 0.0) call abort ()
+ if (sign(1.0, fraction(-0.0)) /= -1.0) call abort ()
+ if (fraction (-2.0_8) /= -0.5) call abort ()
+
+end program test_frac