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

federico <federico.perini at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |federico.perini at gmail dot 
com

--- Comment #12 from federico <federico.perini at gmail dot com> ---
Still present in trunk (https://godbolt.org/z/TxWdYqnE5)

Posting here cause I believe it's the same issue. The leak does not need a
defined assignment. 
A plain call with a function result as the actual argument leaks the same way:

module m
  implicit none
  type :: base
     real, allocatable :: a(:)
  end type base
  type, extends(base) :: ext
     integer, allocatable :: b(:)
  end type ext
  type :: holder
     class(base), allocatable :: p
  contains
     procedure :: set => holder_set
  end type holder
contains
  subroutine holder_set(this, from)
    class(holder), intent(inout) :: this
    type(holder),  intent(in)    :: from
    if (allocated(this%p)) deallocate(this%p)
    if (allocated(from%p)) allocate(this%p, source=from%p)
  end subroutine holder_set
  function fresh() result(h)
    type(holder) :: h
    allocate(ext :: h%p)
    select type (q => h%p)
       type is (ext)
          allocate(q%a(10), q%b(30))
    end select
  end function fresh
end module m

program p
  use m
  implicit none
  type(holder) :: x
  integer :: k
  do k = 1, 3
     call x%set(fresh())          ! q%b of the function result leaks
  end do
  if (allocated(x%p)) deallocate(x%p)
end program p

16.2.0, -O0 and -O2:  3 leaked blocks, one per iteration: the 30-element q%b
13.4.0:               no leak

Workaround that does not leak: associate the function result with a name before
the call.

  associate (r => fresh())
     call x%set(r)
  end associate

Thank you,
Federico

Reply via email to