https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56789

--- Comment #7 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
Ah, I see where the problem is.

Consider the test case

module zero
  implicit none
contains
  subroutine foo(a)
    real, contiguous :: a(:,:)
    print *,a
  end subroutine foo
  subroutine bar(a)
    real :: a(:,:)
    print *,a
  end subroutine bar
end module zero

program main
  use zero
  implicit none
  real, dimension(5,5) :: a
  data a /1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17., &
       & 18.,19.,20.,21.,22.,23.,24.,25./
  call bar(a(1:5:2,1:5:2))
  call foo(a(1:5:2,1:5:2))
end program main

This gets translated to, for the call to bar,

  {
    struct array02_real(kind=4) parm.16;

    parm.16.span = 4;
    parm.16.dtype = {.elem_len=4, .rank=2, .type=3};
    parm.16.dim[0].lbound = 0;
    parm.16.dim[0].ubound = 2;
    parm.16.dim[0].stride = 2;
    parm.16.dim[1].lbound = 0;
    parm.16.dim[1].ubound = 2;
    parm.16.dim[1].stride = 10;
    parm.16.data = (void *) &a[0];
    parm.16.offset = 0;
    bar (&parm.16);
  }

and for the call to foo

  {
    struct array02_real(kind=4) parm.17;
    void * origptr.18;
    void * D.3863;

    parm.17.span = 4;
    parm.17.dtype = {.elem_len=4, .rank=2, .type=3};
    parm.17.dim[0].lbound = 0;
    parm.17.dim[0].ubound = 2;
    parm.17.dim[0].stride = 2;
    parm.17.dim[1].lbound = 0;
    parm.17.dim[1].ubound = 2;
    parm.17.dim[1].stride = 10;
    parm.17.data = (void *) &a[0];
    parm.17.offset = 0;
    origptr.18 = parm.17.data;
    D.3863 = _gfortran_internal_pack (&parm.17);
    parm.17.data = D.3863;
    foo (&parm.17);
    parm.17.data = origptr.18;
    if ((real(kind=4)[0:] *) parm.17.data != (real(kind=4)[0:] *) D.3863)
      {
        _gfortran_internal_unpack (&parm.17, D.3863);
        __builtin_free (D.3863);
      }
  }

The problem is that the data gets packed, but we pass the constructor to the
original, unpacked data to bar.

We should build a new one.

Reply via email to