This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[Fortran] PR 34482: RFC and patch: BOZ to real/complex conversion for some systems
- From: Tobias Burnus <burnus at net-b dot de>
- To: "'fortran at gcc dot gnu dot org'" <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 17 Dec 2007 09:13:14 +0100
- Subject: [Fortran] PR 34482: RFC and patch: BOZ to real/complex conversion for some systems
Assume for the following that 4 is the default integer/real kind and 8
the largest integer kind. In DATA
z'FFFFFFFF'
is has the largest integer kind and is thus identically to
z'00000000FFFFFFFF'
If one now transfers this to a default-kind real, i.e.
real(z'FFFFFFFF')
one transfers an 8 to a 4 byte variable. Depending on the system only
the zeros (00000000) or the ones (FFFFFFFF) are transferred.
I think everyone would expect in this case that the ones/FFFFFFFF are
bit-wise transferred, which the attached patch does by converting the
BOZ to the smallest possible kind; for the example this is 4. This fixes
the PR.
However, I am not sure it does the right thing on all systems for:
real(z'00000000FFFFFFFF',kind=8)
If one converts this to kind 4 ("z'FFFFFFFF'") and transfers it then,
one might get FFFFFFFF00000000 on some sytems instead of
00000000FFFFFFFF. -- Or not?
Jerry, can you check that the patch does the right thing on such
platforms and real(z'00000000FFFFFFFF',kind=8) ?
The attached patch has been built and regression tested on x86-64-linux.
It has also been tested by Jerry for nan_4.f90 on a PowerPC.
If it does not have the issue I outlined above: OK for the trunk?
If it does, one needs to store the number of bits including significant
prefixing zeros. Or should one use MAX(boz_bit_size, lhs_bit_size)?
(The result of the two conversions is not the same!)
I think the Fortran standard does not say at all what is supposed to
happen here. (For integer, gfortran simply assigns the integer and the
conversion to integer is done via GMP; thus z'00000000FFFFFFFF' and
z'FFFFFFFF' are equivalent.)
Tobias
2007-12-17 Tobias Burnus <burnus@net-b.de>
PR fortran/34482
* target-memory.c (gfc_convert_boz): Change BOZ kind to
smallest integer before converting.
Index: gcc/fortran/target-memory.c
===================================================================
--- gcc/fortran/target-memory.c (Revision 131004)
+++ gcc/fortran/target-memory.c (Arbeitskopie)
@@ -596,10 +596,12 @@
return len;
}
+
void
gfc_convert_boz (gfc_expr *expr, gfc_typespec *ts)
{
- size_t buffer_size;
+ size_t buffer_size, boz_bit_size;
+ int index;
unsigned char *buffer;
if (!expr->is_boz)
@@ -616,6 +618,16 @@
else
return;
+ /* Convert BOZ to the smallest possible integer kind. */
+ boz_bit_size = mpz_sizeinbase (expr->value.integer, 2);
+ for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
+ {
+ if ((unsigned) gfc_integer_kinds[index].bit_size >= boz_bit_size)
+ break;
+ }
+ gcc_assert(gfc_integer_kinds[index].radix == 2);
+ expr->ts.kind = gfc_integer_kinds[index].kind;
+
buffer_size = MAX (buffer_size, size_integer (expr->ts.kind));
buffer = (unsigned char*)alloca (buffer_size);