http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47844
Tobias Burnus <burnus at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |pault at gcc dot gnu.org Summary|Pointer-valued function: |I/O: data transfer |Provide wrong result when |statement: Array stride |dereferenced automatically |ignored for pointer-valued |after list-write |function results --- Comment #2 from Tobias Burnus <burnus at gcc dot gnu.org> 2011-02-22 14:45:42 UTC --- Paul, I added you as you are a tad more familiar with the scalarizer than I am. * * * Slightly simplified test case: integer, target :: tgt(5) = [1,2,3,4,5] integer, pointer :: ptr(:) print *, f(tgt) contains function f(x) integer, target :: x(:) integer, pointer :: f(:) f => x(::2) end function f end While "f" correctly sets the stride, it is ignored by the PRINT statement; -fdump-tree-original shows: f (&atmp.8, D.1566); [...] D.1579 = (*(integer(kind=4)[0:] * restrict) atmp.8.data)[S.9]; _gfortran_transfer_integer_write (&dt_parm.5, &D.1579, 4); } S.9 = S.9 + 1; The last line should be S.9 = S.9 + atmp.8.stride, which gets correctly set by "f()". Thus, one needs to teach the scalarizer that the stride does not have to be always 1 for SS_FUNCTION, though the only case I currently can come up with are array-valued pointer-returning functions. I think one should consider adding a is_pointer_result:1 to gfc_ss, which could be set in gfc_walk_function_expr. The scalarizers are set up via gfc_trans_transfer. The "1" setting seems to happen in gfc_conv_ss_startstride: case GFC_SS_CONSTRUCTOR: case GFC_SS_FUNCTION: for (n = 0; n < ss->data.info.dimen; n++) { ss->data.info.start[n] = gfc_index_zero_node; ss->data.info.end[n] = gfc_index_zero_node; ss->data.info.stride[n] = gfc_index_one_node; } break; At some point, it needs to be modified for array-pointer-returning functions; I think that should happen in gfc_conv_loop_setup