This PR was posted to the list by Philippe Schaffnit
http://gcc.gnu.org/ml/fortran/2006-04/msg00131.html
The testcase provided reduces to:
PROGRAM Test
INTEGER :: Array(2, 3) = &
reshape ((/1,4,2,5,3,6/),(/2,3/)), Brray(2, 3) = 0
Array(1,:) = Function_Test (Array(1,:))
print *, Array(1:1,:)
print *, Function_test (Array(1,:) )
Brray(1,:) = Function_Test (Array(1,:))
print *, Brray(1:1,:)
contains
FUNCTION Function_Test (Input)
USE Module_Test
INTEGER, INTENT(IN) :: Input(1:3)
INTEGER :: Function_Test(1:3)
Function_Test = Input + 10
END FUNCTION Function_Test
END PROGRAM Test
which outputs
1 2 3
11 12 13
11 12 13
What is happening is all too apparent from the code for the first assignment
from the function, which I have appended below. Being an array section, the
actual argument is sent to be packed. At the same time, the assignment detects
that the dependency between the lhs and the actual argument and so makes a
temporary for the result. After the function call, the result is transferred
from the temporary and the packed array section is unpacked on top of it. This
latter ensures that the original overwrites the result because the actual
argument is left untouched. The other two uses of the function give the
correct result because there is no dependency.
This can be fixed, I think, by suppressing the dependency temporary, on
detecting that the array will be packed.
Paul
{
int4 A.7[3];
struct array1_int4 atmp.6;
int4[3] * ifm.5;
void * D.928;
void * D.927;
struct array1_int4 parm.4;
parm.4.dtype = 265;
parm.4.dim[0].lbound = 1;
parm.4.dim[0].ubound = 3;
parm.4.dim[0].stride = 2;
parm.4.data = (void *) (int4[0:] *) &array[0];
parm.4.offset = 0;
D.927 = _gfortran_internal_pack (&parm.4);
D.928 = D.927;
ifm.5 = (int4[3] *) D.928;
atmp.6.dtype = 265;
atmp.6.dim[0].stride = 1;
atmp.6.dim[0].lbound = 0;
atmp.6.dim[0].ubound = 2;
atmp.6.data = (void *) &A.7;
atmp.6.offset = 0;
atmp.6.dim[0].stride = 0;
function_test (&atmp.6, D.928);
{
int4 S.8;
S.8 = 0;
while (1)
{
if (S.8 > 2) goto L.2; else (void) 0;
array[(NON_LVALUE_EXPR <S.8> + 1) * 2 + -2] = (*(int4[0:] *)
atmp.6.data)[NON_LVALUE_EXPR <S.8>];
S.8 = S.8 + 1;
}
L.2:;
}
if (D.927 != (int4[0:] *) parm.4.data)
{
_gfortran_internal_unpack (&parm.4, D.927);
_gfortran_internal_free (D.927);
}
else
{
(void) 0;
}
}
--
Summary: Incorrect dependency for assignment from function with
array section actual arg.
Product: gcc
Version: 4.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
AssignedTo: pault at gcc dot gnu dot org
ReportedBy: pault at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27124