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