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

            Bug ID: 113377
           Summary: Wrong code passing optional dummy argument to
                    elemental procedure with optional dummy
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: anlauf at gcc dot gnu.org
  Target Milestone: ---

There are likely several related PRs, e.g. pr67277, but here is a smaller
reproducer:

program p
  implicit none
  integer :: k(4) = 1, m(4)
  m = one (k)
  print *, m
contains
  function one (i, j) result (r)
    integer, intent(in)           :: i(4)
    integer, intent(in), optional :: j
    integer                       :: r(size(i))
    r = two (i, j)  ! scalarizer dereferences loop invariant j ...
  end

  elemental function two (i, j) result (r)
    integer, intent(in)           :: i
    integer, value,      optional :: j
    integer                       :: r
    r = 42*i
  end
end

This crashes in function one.  A scalar invocation does not fail.
The dump-tree suggests that the scalarizer sees the loop invariant j,
unconditionally dereferences it outside the loop, generates code that
unconditionally dereferences j in the invocation of two, and uses a
wrong interface:

integer(kind=4) two (integer(kind=4) & restrict i, integer(kind=4) j,
logical(kind=1) .j)

but one has:

    D.4339 = (integer(kind=4) *) j;
    {
      integer(kind=8) S.3;
      integer(kind=8) D.4341;

      D.4341 = stride.0;
      S.3 = 1;
      while (1)
        {
          if (S.3 > 4) goto L.1;
          *((integer(kind=4) *) __result.0 + (sizetype) ((S.3 * D.4341 +
D.4338) * 4)) = two (&(*i)[S.3 + -1], *D.4339);
          S.3 = S.3 + 1;
        }
      L.1:;

Reply via email to