This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, Fortran] PR fortran/36214: Wrong simplification of BOZ constants


Hi,

this patch fixes PR 36214. The problem is that gfc_interpret_float calls mpfr_init at its beginning to initialize the mpfr-variable, but it does not set the mpfr default precision, thus accepting whatever this precision is.

This lead to the strange behaviour that declaring a dummy real(kind=4) variable somewhere in the test made it fail, because then the default precision was set for kind=4 from the dummy variable's initialization, and real(b'xxx', kind=8) returned a mpfr value with kind=4 precision.

The fix is easy, just set the default precision to a suitable value for the kind parameter in gfc_interpret_float. On the way I picked up some formatting fixes, but I can remove them of course if you want.

Regression testing on GNU/Linux-x86-32 at the moment. Ok to commit if no failures? Should I backport this to 4.3, too? (If the problem exists there, too, I've not yet tried.)

Yours,
Daniel

--
Done:     Arc-Bar-Cav-Sam-Val-Wiz, Dwa-Elf-Gno-Hum-Orc, Law-Neu-Cha, Fem-Mal
To go:    Hea-Kni-Mon-Pri-Ran-Rog-Tou
2008-09-10  Daniel Kraft  <d@domob.eu>

	PR fortran/36214
	* simplify.c (simplify_cmplx): Added linebreak to long line.
	* target-memory.c (gfc_convert_boz): Fix indentation.
	(gfc_interpret_float): Set mpfr precision to right value before
	calling mpfr_init.

2008-09-10  Daniel Kraft  <d@domob.eu>

	PR fortran/36214
	* gfortran.dg/boz_13.f90: New test.
	* gfortran.dg/boz_14.f90: New test.
Index: gcc/fortran/target-memory.c
===================================================================
--- gcc/fortran/target-memory.c	(revision 140239)
+++ gcc/fortran/target-memory.c	(working copy)
@@ -349,8 +349,9 @@ gfc_interpret_integer (int kind, unsigne
 
 int
 gfc_interpret_float (int kind, unsigned char *buffer, size_t buffer_size,
-		 mpfr_t real)
+		     mpfr_t real)
 {
+  gfc_set_model_kind (kind);
   mpfr_init (real);
   gfc_conv_tree_to_mpfr (real,
 			 native_interpret_expr (gfc_get_real_type (kind),
@@ -699,10 +700,8 @@ gfc_convert_boz (gfc_expr *expr, gfc_typ
     }
 
   for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
-    {
-	if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size)
-	  break;
-    }
+    if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size)
+      break;
 
   expr->ts.kind = gfc_integer_kinds[index].kind;
   buffer_size = MAX (buffer_size, size_integer (expr->ts.kind));
Index: gcc/fortran/simplify.c
===================================================================
--- gcc/fortran/simplify.c	(revision 140239)
+++ gcc/fortran/simplify.c	(working copy)
@@ -884,7 +884,8 @@ simplify_cmplx (const char *name, gfc_ex
 	{
 	case BT_INTEGER:
 	  if (!y->is_boz)
-	    mpfr_set_z (result->value.complex.i, y->value.integer, GFC_RND_MODE);
+	    mpfr_set_z (result->value.complex.i, y->value.integer,
+			GFC_RND_MODE);
 	  break;
 
 	case BT_REAL:
Index: gcc/testsuite/gfortran.dg/boz_14.f90
===================================================================
--- gcc/testsuite/gfortran.dg/boz_14.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/boz_14.f90	(revision 0)
@@ -0,0 +1,18 @@
+! { dg-do run }
+
+! PR fortran/36214
+! For BOZ-initialization of floats, the precision used to be wrong sometimes.
+
+   implicit none
+   real(4) r
+   real(8) rd
+   complex(8) z
+   rd = &
+    real (b'00000000000000000000000000000000&
+           &01000000001010010101001111111101',8)
+   z  = &
+    cmplx(b'00000000000000000000000000000000&
+           &01000000001010010101001111111101',0,8)
+   r = 0.
+   if (z /= rd) call abort
+   end
Index: gcc/testsuite/gfortran.dg/boz_13.f90
===================================================================
--- gcc/testsuite/gfortran.dg/boz_13.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/boz_13.f90	(revision 0)
@@ -0,0 +1,13 @@
+! { dg-do run }
+
+! PR fortran/36214
+! For BOZ-initialization of floats, the precision used to be wrong sometimes.
+
+implicit none
+   real, parameter :: r = 0.0
+   real(kind=8), parameter :: rd = real (z'00000000&
+                                          &402953FD', 8)
+
+   if (real (z'00000000&
+              &402953FD', 8) /= rd) call abort
+end

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]