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);
  }
}

Reply via email to