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.