https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122080
--- Comment #6 from anlauf at gcc dot gnu.org ---
(In reply to Henri Menke from comment #5)
> Apologies for supplying non-conforming code.
>
> When I add an explicit interface for the inner routine
>
> subroutine outer(optarr)
> real, optional, intent(in) :: optarr(:,:)
> interface
> subroutine inner(optarr)
> real, optional, intent(in) :: optarr(:,:)
> end subroutine inner
> end interface
> call inner(optarr)
> end subroutine outer
>
> I obtain identical trees to
>
> subroutine outer(optarr)
> real, optional, intent(in) :: optarr(:,:)
> call inner(optarr)
> end subroutine outer
>
> with GNU Fortran (GCC) 15.1.0.
I do not get a reference to _gfortran_internal_pack /
_gfortran_internal_unpack,
the array is passed as expected when it is present:
__attribute__((fn spec (". r ")))
void outer (struct array02_real(kind=4) * restrict optarr)
{
integer(kind=8) ubound.0;
integer(kind=8) stride.1;
integer(kind=8) ubound.2;
integer(kind=8) stride.3;
integer(kind=8) offset.4;
integer(kind=8) size.5;
real(kind=4)[0:D.4694] * restrict optarr.0;
integer(kind=8) D.4694;
bitsizetype D.4695;
sizetype D.4696;
if (optarr != 0B && (real(kind=4)[0:] * restrict) optarr->data != 0B)
{
{
integer(kind=8) D.4693;
D.4693 = optarr->dim[0].stride;
stride.1 = D.4693 != 0 ? D.4693 : 1;
optarr.0 = (real(kind=4)[0:D.4694] * restrict) optarr->data;
ubound.0 = (optarr->dim[0].ubound - optarr->dim[0].lbound) + 1;
stride.3 = optarr->dim[1].stride;
ubound.2 = (optarr->dim[1].ubound - optarr->dim[1].lbound) + 1;
size.5 = stride.3 * NON_LVALUE_EXPR <ubound.2>;
offset.4 = -NON_LVALUE_EXPR <stride.1> - NON_LVALUE_EXPR <stride.3>;
D.4694 = size.5 + -1;
D.4695 = (bitsizetype) (sizetype) NON_LVALUE_EXPR <size.5> * 32;
D.4696 = (sizetype) NON_LVALUE_EXPR <size.5> * 4;
}
}
else
{
optarr.0 = 0B;
}
{
integer(kind=8) D.4676;
integer(kind=8) D.4677;
struct array02_real(kind=4) parm.6;
integer(kind=8) D.4684;
integer(kind=8) D.4685;
struct array02_real(kind=4) * D.4686;
D.4676 = ubound.0;
D.4677 = ubound.2;
parm.6.span = 4;
parm.6.dtype = {.elem_len=4, .version=0, .rank=2, .type=3};
D.4684 = stride.1;
parm.6.dim[0].lbound = 1;
parm.6.dim[0].ubound = D.4676;
parm.6.dim[0].stride = NON_LVALUE_EXPR <D.4684>;
D.4685 = stride.3;
parm.6.dim[1].lbound = 1;
parm.6.dim[1].ubound = D.4677;
parm.6.dim[1].stride = NON_LVALUE_EXPR <D.4685>;
parm.6.data = (void *) optarr.0;
parm.6.offset = -NON_LVALUE_EXPR <D.4684> - NON_LVALUE_EXPR <D.4685>;
D.4686 = optarr.0 != 0B ? &parm.6 : 0B;
inner (D.4686);
}
}