[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