[PATCH, Fortran] pad char to int conversions with spaces instead of zeros (legacy)

Jakub Jelinek jakub@redhat.com
Mon Dec 10 17:12:00 GMT 2018


On Mon, Dec 10, 2018 at 02:09:50PM +0000, Mark Eggleston wrote:
> 
> On 06/12/2018 10:20, Mark Eggleston wrote:
> > > Yes. Mark, you'll need to also patch iresolve.c (gfc_resolve_transfer)
> > > to affect non-constant resolution.
> > Thanks for the hint.
> 
> I've looked at gfc_resolve_transfer regarding handling of padding when a
> character variable is passed to transfer instead of a literal. This routine
> is not called so can't be where a variable would be handled.
> 
> Don't yet know where to make the change.

I think you want to change gfc_conv_intrinsic_transfer
For the scalar case, which is the one for which I've posted testcase, there
is:
  extent = fold_build2_loc (input_location, MIN_EXPR, gfc_array_index_type,
                            dest_word_len, source_bytes);
  extent = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
                            extent, gfc_index_zero_node);
and later:
      tmp = build_call_expr_loc (input_location,
                             builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
                             fold_convert (pvoid_type_node, tmp),
                             fold_convert (pvoid_type_node, ptr),
                             fold_convert (size_type_node, extent));
      gfc_add_expr_to_block (&se->pre, tmp);
I guess you want to add after this, guarded with flag_dec only,
code to compare (at runtime) if extent < dest_word_len and if so,
use fill_with_spaces to pad it with spaces at the end (from
that first memcpy's argument + extent dest_word_len - extent bytes),
with a comment why you are doing it.  Guess the array case will need
something similar.  But, for these runtime checks, guess you should start by
looking what the other compilers are exactly doing for the different kinds
of transfers, if they pad for non-constants at all, if they only pad if
transfer is from a character object to whatever, etc.

Looking at ifort on godbolt
function foo (e)
  integer(kind=8) :: foo
  character(len=4) :: e
  foo = transfer(e, 1_8)
end
I see it calls for_cpystr (..., 8, ..., 4, ...)
so I guess it uses standard library function to copy string into the
destination in that case, so essentially what gfc_trans_string_copy
does inline or our fstrcpy (internal library function).

	Jakub



More information about the Gcc-patches mailing list