Patchwork [Fortran] PR52413 - Incorrect behavior of FRACTION when applied to a constant

login
register
mail settings
Submitter Dominique Dhumieres
Date June 23, 2013, 9:43 p.m.
Message ID <20130623214358.1338A3BE1B@mailhost.lps.ens.fr>
Download mbox | patch
Permalink /patch/253606/
State New
Headers show

Comments

Dominique Dhumieres - June 23, 2013, 9:43 p.m.
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.
Tobias Burnus - June 24, 2013, 8:49 a.m.
Dominique Dhumieres wrote:
> 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?

OK. Thanks for the patches Steve and FX - and to Dominique for combining 
the two and creating the test case.

I have committed it as Rev. 200361.

> 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.

The syntax is to place the function name in parentheses, i.e.

	* simplify.c (gfc_simplify_fraction): Fix the sign of negative values.


Tobias
Dominique Dhumieres - June 24, 2013, 11:12 a.m.
Tobias,

> I have committed it as Rev. 200361.

Thanks for the quick commit. No backport?

Dominique

Patch

--- ../_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