[Patch, fortran] PR31217 - ICE using FORALL on character substrings

Paul Thomas paulthomas2@wanadoo.fr
Thu Oct 25 23:39:00 GMT 2007


Well here is the resubmission, in response to Dominique's failing case, 
and, just to show that our's is a policy of continuous improvement, it 
fixes PR33686 as well.

This latter was triggered by a contribution from Dick Hendrickson on 
comp.lang.fortran, under " Most elegant syntax for inverting a 
permutation?" 20071006:
  integer :: p(4) = (/2,4,1,3/)
  forall (i = 1:4) p(p(i)) = i
  print *, p
end

This gave a wrong answer because the dependency internal to the 'value' 
expression was not resolved.  Since, in principle, this dependency could 
span all and any of the references, in any combinantion, the only way to 
cope is to copy the whole array to a temporary, ouside of the FORALL 
construct, associate a symtree to it and replace the original symtree in 
all references.

Dominique's
  character(LEN=12) :: b = "123456789012"
  forall (i = 3:10) b(i:i+2) = b(i-2:i)
  IF (b .ne. "121234567890") CALL abort ()
END

is solved in the same fashion.

Whilst it is a bit of a grind, this part of the patch is straightforward 
and relatively easily understood from the patch to trans-stmt.c and the 
ChangeLog.  Note that the fix for assignments (PR33811) remains as it 
was in the original submission.  A lot of the symbol/symtree code was 
lifted directly from Richard Sandiford's interface routines in 
trans-expr.c.  Unfortunately, these did not seem to be readily liftable 
for this patch.

In the course of writing this patch, I found myself needing to write yet 
another function to traverse an expression and all its sub-expressions, 
comparing EXPR_VARIABLE with a symbol and doing something if they are 
the same.  I therefore did something that I have meant to do for a long 
time and that is to write a general expression traverser, 
gfc_traverse_expr.  As soon as this patch is put to bed, I will clean up 
the several other cases that can use this general function.  In 
addition, there is at least one more to come - the pureness of statement 
functions, PR29389.

Regtested on Cygwin_NT/amd64 - will repeat on x86_ia64 just as soon as I 
get home.

OK for trunk?

Paul

2007-10-25  Paul Thomas <pault@gcc.gnu.org>

    PR fortran/31217
    PR fortran/33811
    PR fortran/33686
    * trans-array.c (gfc_conv_loop_setup): Send a complete type to
    gfc_trans_create_temp_array if the temporary is character.
    * trans-stmt.c (gfc_trans_assign_need_temp): Do likewise for
    allocate_temp_for_forall_nest.
    (forall_replace): New function.
    (forall_replace_symtree): New function.
    (forall_restore): New function.
    (forall_restore_symtree): New function.
    (forall_make_variable_temp): New function.
    (check_forall_dependencies): New function.
    (cleanup_forall_symtrees): New function.
    gfc_trans_forall_1): Add and initialize pre and post blocks.
    Call check_forall_dependencies to check for all dependencies
    and either trigger second forall block to copy temporary or
    copy lval, outside the forall construct and replace all
    dependent references. After assignment clean-up and coalesce
    the blocks at the end of the function.
    * gfortran.h : Add prototypes for gfc_traverse_expr and
    find_forall_index.
    expr.c (gfc_traverse_expr): New function to traverse expression
    and visit all subexpressions, under control of a logical flag,
    a symbol and an integer pointer. The slave function is caller
    defined and is only called on EXPR_VARIABLE.
    (expr_set_symbols_referenced): Called by above to set symbols
    referenced.
    (gfc_expr_set_symbols_referenced): Rework of this function to
    use two new functions above.
    * resolve.c (find_forall_index): Rework with gfc_traverse_expr,
    using forall_index.
    (forall_index): New function used by previous.
    * dependency.c (gfc_check_dependency): Use gfc_dep_resolver for
    all references, not just REF_ARRAY.
    (gfc_dep_resolver): Correct the logic for substrings so that
    overlapping arrays are handled correctly.

2007-10-25  Paul Thomas <pault@gcc.gnu.org>

    PR fortran/31217
    PR fortran/33811
    * gfortran.dg/forall_12.f90: New test.

    PR fortran/33686
    * gfortran.dg/forall_13.f90: New test.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: resubmit.diff
Type: text/x-patch
Size: 25969 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20071025/01bb6828/attachment.bin>


More information about the Fortran mailing list