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

Reply via email to