[patch, fortran] Fix a TRANSFER folding bug, rework Hollerith handling.
Brooks Moses
brooks.moses@codesourcery.com
Mon May 28 07:36:00 GMT 2007
:ADDPATCH fortran:
This change is a bugfix to the TRANSFER constant-folding, masquerading
as a complete reworking of the way we handle Hollerith constants. :)
The problem, fundamentally, is this: If one takes a strict
interpretation of the Fortran standard, the following little program is
required to return 42:
logical, parameter :: A = TRANSFER (4, .true.)
integer, parameter :: I = TRANSFER (A, 0)
write(*,*) I
This currently does not work with the constant-folding. The transfer to
A determines that 4 is nonzero, and thus A has a logical value of true,
and the gfc_expr that is created merely stores that value. Then, the
constant-folding to I knows that a value of true is stored as if it has
an integer value of 1, and the output is 1.
To fix this, the gfc_expr that we store for A obviously has to include
its in-memory representation along with its actual semantic value.
Now, as it happens, we've already got a Fortran functionality that's
storing in-memory representations; that's what Hollerith constants do.
This patch slightly rearranges how those are handled, so that the
in-memory representation is no longer part of the "value" union, and
thus a gfc_expr can now have a "value" and an in-memory representation
simultaneously. When both of them are set, the TRANSFER intrinsic and
gfc_conv_constant_to_tree use the in-memory representation, whereas any
other constant-folding (of intrinsics, operators, etc.) use the value.
Once that's done, we can rip out the from_H field in gfc_expr. Its only
remaining purpose is to guard against trying to access the value of
constants converted from Holleriths, and it's simpler just to give them
values using the "interpret" functions from target-memory.
So, that's really just about it, except for cleaning up a few details,
and adding a new testcase to demonstrate that this works correctly.
(Unfortunately, the testcase is only currently working with -O0;
something weird is happening in the optimizers that I'll need to track
down.)
My next project will be folding BOZ-literals into this system, I think;
that will be useful to handle how Fortran 2003 does REAL(Z'FFF0') and
that kind of mess -- and, coincidentally, give us a very small start on
Fortran 2008. :)
------------------------------------------------------------------------------
2007-05-27 Brooks Moses <brooks.moses@codesourcery.com>
* gfortran.h (gfc_expr): Remove from_H, add "representation"
struct.
* primary.c (match_hollerith_constant): Store the representation of
the Hollerith in representation, not in value.character.
* arith.c: Add dependency on target-memory.h.
(eval_intrinsic): Remove check for from_H.
(hollerith2representation): New function.
(gfc_hollerith2int): Determine value of the new constant.
(gfc_hollerith2real): Likewise.
(gfc_hollerith2complex): Likewise.
(gfc_hollerith2logical): Likewise.
(gfc_hollerith2character): Point both representation.string and
value.character.string at the value string.
* data.c (create_character_initializer): For BT_HOLLERITH
rvalues, get the value from the representation rather than
value.character.
* expr.c (free_expr0): Update handling of BT_HOLLERITH values
and values with representation.string.
(gfc_copy_expr): Likewise.
* intrinsic.c (do_simplify): Remove special treatement of
variables resulting from Hollerith constants.
* dump-parse-trees.c (gfc_show_expr): Update handling of
Holleriths.
* trans-const.c (gfc_conv_constant_to_tree): Replace from_H
check with check for representation.string; get Hollerith
representation from representation.string, not value.character.
* trans-expr.c (is_zero_initializer_p): Replace from_H check
with check for representation.string.
* trans-stmt.c (gfc_trans_integer_select): Use
gfc_conv_mpz_to_tree for case values, so as to avoid picking up
the memory representation if the case is given by a transfer
expression.
* target-memory.c (gfc_target_encode_expr): Use the known memory
representation rather than the value, if it exists.
(gfc_target_interpret_expr): Store the memory representation of
the interpreted expression as well as its value.
(interpret_integer): Move to gfc_interpret_integer, make
non-static.
(interpret_float): Move to gfc_interpret_float, make non-static.
(interpret_complex): Move to gfc_interpret_complex, make
non-static.
(interpret_logical): Move to gfc_interpret_logical, make
non-static.
(interpret_character): Move to gfc_interpret_character, make
non-static.
(interpret_derived): Move to gfc_interpret_derived, make
non-static.
* target-memory.h: Add prototypes for newly-exported
gfc_interpret_* functions.
------------------------------------------------------------------------------
2007-05-27 Brooks Moses <brooks.moses@codesourcery.com>
* gfortran.dg/transfer_simplify_3.f90: New test.
------------------------------------------------------------------------------
Regression-tested on powerpc-apple-darwin8.9.0. Ok for trunk?
- Brooks
-------------- next part --------------
A non-text attachment was scrubbed...
Name: no_hollerith_4.diff
Type: text/x-patch
Size: 24479 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20070528/146664f3/attachment.bin>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: transfer_simplify_3.f90
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20070528/146664f3/attachment.f90>
More information about the Fortran
mailing list