This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/47844] I/O: data transfer statement: Array stride ignored for pointer-valued function results
- From: "burnus at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 22 Feb 2011 14:45:59 +0000
- Subject: [Bug fortran/47844] I/O: data transfer statement: Array stride ignored for pointer-valued function results
- Auto-submitted: auto-generated
- References: <bug-47844-4@http.gcc.gnu.org/bugzilla/>
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