This one came up on clf yesterday. Thanks to Jeurgen Reuter for posting the PR.
This is further fallout from the array descriptor changes. I decided not to pick out the special case involved but to set the 'span' field for all new (ie. 'parm') descriptors. A bit of fiddling around with gfc_get_array_span was needed to punt on incomplete types, unless a length could be found in the gfc_expr. Bootstraps and regtests on FC28/x86_64 - OK for 8- and 9-branches? Paul 2018-09-18 Paul Thomas <pa...@gcc.gnu.org> PR fortran/87336 * trans-array.c (gfc_get_array_span): Try to get the element length of incomplete types. Return NULL_TREE otherwise. (gfc_conv_expr_descriptor): Only set the 'span' field if the above does not return NULL_TREE. Set 'span' field if possible for all new descriptors. 2018-09-18 Paul Thomas <pa...@gcc.gnu.org> PR fortran/87336 * gfortran.dg/pointer_array_10.f90 : New test. * gfortran.dg/assign_10.f90 : Increase 'parm' count to 20. * gfortran.dg/transpose_optimization_2.f90 : Increase 'parm' count to 72.
Index: gcc/fortran/trans-array.c =================================================================== *** gcc/fortran/trans-array.c (revision 264364) --- gcc/fortran/trans-array.c (working copy) *************** gfc_get_array_span (tree desc, gfc_expr *** 849,858 **** else { /* If none of the fancy stuff works, the span is the element ! size of the array. */ tmp = gfc_get_element_type (TREE_TYPE (desc)); ! tmp = fold_convert (gfc_array_index_type, ! size_in_bytes (tmp)); } return tmp; } --- 849,870 ---- else { /* If none of the fancy stuff works, the span is the element ! size of the array. Attempt to deal with unbounded character ! types if possible. Otherwise, return NULL_TREE. */ tmp = gfc_get_element_type (TREE_TYPE (desc)); ! if (tmp && TREE_CODE (tmp) == ARRAY_TYPE ! && TYPE_MAX_VALUE (TYPE_DOMAIN (tmp)) == NULL_TREE) ! { ! if (expr->expr_type == EXPR_VARIABLE ! && expr->ts.type == BT_CHARACTER) ! tmp = fold_convert (gfc_array_index_type, ! gfc_get_expr_charlen (expr)); ! else ! tmp = NULL_TREE; ! } ! else ! tmp = fold_convert (gfc_array_index_type, ! size_in_bytes (tmp)); } return tmp; } *************** gfc_conv_expr_descriptor (gfc_se *se, gf *** 7074,7080 **** /* ....and set the span field. */ tmp = gfc_get_array_span (desc, expr); ! gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp); } else if (se->want_pointer) { --- 7086,7093 ---- /* ....and set the span field. */ tmp = gfc_get_array_span (desc, expr); ! if (tmp != NULL_TREE) ! gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp); } else if (se->want_pointer) { *************** gfc_conv_expr_descriptor (gfc_se *se, gf *** 7344,7356 **** desc = info->descriptor; if (se->direct_byref && !se->byref_noassign) { ! /* For pointer assignments we fill in the destination.... */ parm = se->expr; parmtype = TREE_TYPE (parm); - - /* ....and set the span field. */ - tmp = gfc_get_array_span (desc, expr); - gfc_conv_descriptor_span_set (&loop.pre, parm, tmp); } else { --- 7357,7365 ---- desc = info->descriptor; if (se->direct_byref && !se->byref_noassign) { ! /* For pointer assignments we fill in the destination. */ parm = se->expr; parmtype = TREE_TYPE (parm); } else { *************** gfc_conv_expr_descriptor (gfc_se *se, gf *** 7388,7393 **** --- 7397,7407 ---- } } + /* Set the span field. */ + tmp = gfc_get_array_span (desc, expr); + if (tmp != NULL_TREE) + gfc_conv_descriptor_span_set (&loop.pre, parm, tmp); + offset = gfc_index_zero_node; /* The following can be somewhat confusing. We have two Index: gcc/testsuite/gfortran.dg/assign_10.f90 =================================================================== *** gcc/testsuite/gfortran.dg/assign_10.f90 (revision 264364) --- gcc/testsuite/gfortran.dg/assign_10.f90 (working copy) *************** end *** 23,27 **** ! cases will all yield a temporary, so that atmp appears 18 times. ! Note that it is the kind conversion that generates the temp. ! ! ! { dg-final { scan-tree-dump-times "parm" 18 "original" } } ! { dg-final { scan-tree-dump-times "atmp" 18 "original" } } --- 23,27 ---- ! cases will all yield a temporary, so that atmp appears 18 times. ! Note that it is the kind conversion that generates the temp. ! ! ! { dg-final { scan-tree-dump-times "parm" 20 "original" } } ! { dg-final { scan-tree-dump-times "atmp" 18 "original" } } Index: gcc/testsuite/gfortran.dg/pointer_array_10.f90 =================================================================== *** gcc/testsuite/gfortran.dg/pointer_array_10.f90 (nonexistent) --- gcc/testsuite/gfortran.dg/pointer_array_10.f90 (working copy) *************** *** 0 **** --- 1,27 ---- + ! { dg-do run } + ! + ! Test the fix for PR87336, in which the 'span' field of the array + ! descriptor, passed to 'show', was not set. + ! + ! Contributed by Juergen Reuter <juergen.reu...@desy.de> following + ! a posting to clf by 'Spectrum'. + ! + program main + implicit none + integer, target :: a( 2:4 ) + + a = [2,3,4] + ! print *, "a [before] = ", a + call show( a ) + ! print *, "a [after] = ", a + if (any (a .ne. [200,300,400])) stop 1 + + contains + subroutine show( arr ) + integer, pointer, intent(in) :: arr(:) + ! print *, "arr = ", arr + ! print *, "bounds = ", lbound(arr), ubound(arr) + arr(:) = [200,300,400] + ! print *, "arr2= ", arr + end subroutine show + end program Index: gcc/testsuite/gfortran.dg/transpose_optimization_2.f90 =================================================================== *** gcc/testsuite/gfortran.dg/transpose_optimization_2.f90 (revision 264364) --- gcc/testsuite/gfortran.dg/transpose_optimization_2.f90 (working copy) *************** end *** 60,64 **** ! ! The check below for temporaries gave 14 and 33 for "parm" and "atmp". ! ! ! { dg-final { scan-tree-dump-times "parm" 66 "original" } } ! { dg-final { scan-tree-dump-times "atmp" 12 "original" } } --- 60,64 ---- ! ! The check below for temporaries gave 14 and 33 for "parm" and "atmp". ! ! ! { dg-final { scan-tree-dump-times "parm" 72 "original" } } ! { dg-final { scan-tree-dump-times "atmp" 12 "original" } }