This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, Fortran] PR fortran/36214: Wrong simplification of BOZ constants
- From: Daniel Kraft <d at domob dot eu>
- To: Fortran List <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 10 Sep 2008 21:11:50 +0200
- Subject: [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