view gcc/testsuite/gfortran.dg/pdt_15.f03 @ 118:fd00160c1b76

ifdef TARGET_64BIT
author mir3636
date Tue, 27 Feb 2018 15:01:35 +0900
parents 04ced10e8804
children 84e7813d76e9
line wrap: on
line source

! { 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) call abort
    if (int (pop_8 (root)) .ne. 2) call abort
    if (int (pop_8 (root)) .ne. 1) call abort
!    if (int (pop_8 (root)) .ne. 0) call abort
  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" 7 "original" } }
! { dg-final { scan-tree-dump-times "__builtin_free" 14 "original" } }