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

            Bug ID: 128357
           Summary: Parenthesized variable with allocatable components
                    leaks
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jvdelisle at gcc dot gnu.org
  Target Milestone: ---

Parenthesized variable with allocatable components leaks as actual argument or
ASSOCIATE selector; scalar CLASS one aliases

When a variable whose type has allocatable components is put in parentheses and
used as an actual argument or as an ASSOCIATE selector, gfortran leaks memory.
A parenthesized scalar CLASS variable is not copied at all: the dummy aliases
the variable.

1) Derived array: the temporary array for (ta) is never freed.

module m
  implicit none
  type :: t
    integer :: c = 7
    integer, allocatable :: v(:)
  end type
contains
  subroutine s (x)
    type(t), intent(in) :: x(:)
    if (x(2)%v(2) /= 2) stop 1
  end subroutine
end module
program p
  use m
  implicit none
  type(t) :: ta(2)
  ta(1) = t (1, [1])
  ta(2) = t (2, [2, 2])
  call s ((ta))
end program

$ gfortran -fsanitize=address pr.f90 && ./a.out
SUMMARY: AddressSanitizer: 144 byte(s) leaked in 1 allocation(s).
  (allocated in p at the "call s ((ta))" line)

2) CLASS array and scalar CLASS:

module m
  implicit none
  type :: t
    integer :: c = 7
    integer, allocatable :: v(:)
  end type
contains
  subroutine sc (x)
    class(t), intent(in) :: x(:)
    if (x(2)%v(2) /= 2) stop 3
  end subroutine
  subroutine sq (x, z)
    class(*), intent(in) :: x
    complex, intent(inout) :: z
    z = (0., 0.)
    select type (x)
    type is (complex)
      if (x /= (5., 6.)) stop 1
    end select
  end subroutine
end module
program p
  use m
  implicit none
  type(t), target :: ta(2)
  class(t), pointer :: qa(:)
  complex, target :: zs = (5., 6.)
  class(*), pointer :: q
  ta(1) = t (1, [1])
  ta(2) = t (2, [2, 2])
  qa => ta
  call sc ((qa))
  associate (b => (qa))
    if (any (b%c /= [1, 2])) stop 2
  end associate
  q => zs
  call sq ((q), zs)
end program

The element copies made by _copy for (qa) are never freed, both at "call sc
((qa))" and at the ASSOCIATE (ASan reports leaks from __copy_m_T), and the
program stops with STOP 1 because x in sq aliases zs instead of holding a copy
of its value.

Reply via email to