blob: 30c7f18b709b8ee5799af7351f63cd2ffcb271be [file] [log] [blame]
! { dg-do compile }
! { dg-options "-fdump-tree-original" }
!
! Test the fix for PR82375. This is a wrinkle on the the allocatable
! version of pdt_13.f03, pdt_14.f03, whereby 'root' is now declared
! in a subroutine so that it should be cleaned up automatically. This
! is best tested with valgrind or its like.
! In addition, the field 'n' has now become a parameterized length
! array to verify that the combination of allocatable components and
! parameterization works correctly.
!
! Based on contribution by Ian Chivers <ian@rhymneyconsulting.co.uk>
!
module precision_module
implicit none
integer, parameter :: sp = selected_real_kind(6, 37)
integer, parameter :: dp = selected_real_kind(15, 307)
integer, parameter :: qp = selected_real_kind( 30, 291)
end module precision_module
module link_module
use precision_module
type link(real_kind, mat_len)
integer, kind :: real_kind
integer, len :: mat_len
real (kind=real_kind) :: n(mat_len)
type (link(real_kind, :)), allocatable :: next
end type link
contains
function push_8 (self, arg) result(current)
real(dp) :: arg
type (link(real_kind=dp, mat_len=:)), allocatable, target :: self
type (link(real_kind=dp, mat_len=:)), pointer :: current
if (allocated (self)) then
current => self
do while (allocated (current%next))
current => current%next
end do
allocate (link(real_kind=dp, mat_len=1) :: current%next)
current => current%next
else
allocate (link(real_kind=dp, mat_len=1) :: self)
current => self
end if
current%n(1) = arg
end function push_8
function pop_8 (self) result(res)
type (link(real_kind=dp, mat_len=:)), allocatable, target :: self
type (link(real_kind=dp, mat_len=:)), pointer:: current => NULL()
type (link(real_kind=dp, mat_len=:)), pointer :: previous => NULL()
real(dp) :: res
res = 0.0_8
if (allocated (self)) then
current => self
previous => self
do while (allocated (current%next))
previous => current
current => current%next
end do
res = current%n(1)
if (.not.allocated (previous%next)) then
deallocate (self)
else
deallocate (previous%next)
end if
end if
end function pop_8
end module link_module
program ch2701
use precision_module
use link_module
implicit none
integer, parameter :: wp = dp
call foo
contains
subroutine foo
type (link(real_kind=wp, mat_len=:)), allocatable :: root
type (link(real_kind=wp, mat_len=:)), pointer :: current => NULL()
current => push_8 (root, 1.0_8)
current => push_8 (root, 2.0_8)
current => push_8 (root, 3.0_8)
if (int (pop_8 (root)) .ne. 3) STOP 1
if (int (pop_8 (root)) .ne. 2) STOP 2
if (int (pop_8 (root)) .ne. 1) STOP 3
! if (int (pop_8 (root)) .ne. 0) STOP 4
end subroutine
end program ch2701
! { dg-final { scan-tree-dump-times "Pdtlink_8._deallocate " 5 "original" } }
! { dg-final { scan-tree-dump-times ".n.data = 0B" 8 "original" } }
! { dg-final { scan-tree-dump-times "__builtin_free" 14 "original" } }