Mercurial > hg > CbC > CbC_gcc
diff gcc/testsuite/gfortran.dg/allocate_with_source_13.f03 @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/testsuite/gfortran.dg/allocate_with_source_13.f03 Fri Oct 27 22:46:09 2017 +0900 @@ -0,0 +1,220 @@ +! { dg-do compile } +! +! Tests the fix for PR61819. +! +! Contributed by Salvatore Filippone <sfilippone@uniroma2.it> +! +module foo_base_mod + integer, parameter :: foo_ipk_ = kind(1) + integer, parameter :: foo_dpk_ = kind(1.d0) + type foo_d_base_vect_type + real(foo_dpk_), allocatable :: v(:) + contains + procedure :: free => d_base_free + procedure :: get_vect => d_base_get_vect + procedure :: allocate => d_base_allocate + end type foo_d_base_vect_type + + + type foo_d_vect_type + class(foo_d_base_vect_type), allocatable :: v + contains + procedure :: free => d_vect_free + procedure :: get_vect => d_vect_get_vect + end type foo_d_vect_type + + type foo_desc_type + integer(foo_ipk_) :: nl=-1 + end type foo_desc_type + + +contains + + subroutine foo_init(ictxt) + integer :: ictxt + end subroutine foo_init + + + subroutine foo_exit(ictxt) + integer :: ictxt + end subroutine foo_exit + + subroutine foo_info(ictxt,iam,np) + integer(foo_ipk_) :: ictxt,iam,np + iam = 0 + np = 1 + end subroutine foo_info + + subroutine foo_cdall(ictxt,map,info,nl) + integer(foo_ipk_) :: ictxt, info + type(foo_desc_type) :: map + integer(foo_ipk_), optional :: nl + + if (present(nl)) then + map%nl = nl + else + map%nl = 1 + end if + end subroutine foo_cdall + + subroutine foo_cdasb(map,info) + integer(foo_ipk_) :: info + type(foo_desc_type) :: map + if (map%nl < 0) map%nl=1 + end subroutine foo_cdasb + + + subroutine d_base_allocate(this,n) + class(foo_d_base_vect_type), intent(out) :: this + + allocate(this%v(max(1,n))) + + end subroutine d_base_allocate + + subroutine d_base_free(this) + class(foo_d_base_vect_type), intent(inout) :: this + if (allocated(this%v)) & + & deallocate(this%v) + end subroutine d_base_free + + function d_base_get_vect(this) result(res) + class(foo_d_base_vect_type), intent(inout) :: this + real(foo_dpk_), allocatable :: res(:) + + if (allocated(this%v)) then + res = this%v + else + allocate(res(1)) + end if + end function d_base_get_vect + + subroutine d_vect_free(this) + class(foo_d_vect_type) :: this + if (allocated(this%v)) then + call this%v%free() + deallocate(this%v) + end if + end subroutine d_vect_free + + function d_vect_get_vect(this) result(res) + class(foo_d_vect_type) :: this + real(foo_dpk_), allocatable :: res(:) + + if (allocated(this%v)) then + res = this%v%get_vect() + else + allocate(res(1)) + end if + end function d_vect_get_vect + + subroutine foo_geall(v,map,info) + type(foo_d_vect_type), intent(out) :: v + type(foo_Desc_type) :: map + integer(foo_ipk_) :: info + + allocate(foo_d_base_vect_type :: v%v,stat=info) + if (info == 0) call v%v%allocate(map%nl) + end subroutine foo_geall + +end module foo_base_mod + + +module foo_scalar_field_mod + use foo_base_mod + implicit none + + type scalar_field + type(foo_d_vect_type) :: f + type(foo_desc_type), pointer :: map => null() + contains + procedure :: free + end type + + integer(foo_ipk_), parameter :: nx=4,ny=nx, nz=nx + type(foo_desc_type), allocatable, save, target :: map + integer(foo_ipk_) ,save :: NumMy_xy_planes + integer(foo_ipk_) ,parameter :: NumGlobalElements = nx*ny*nz + integer(foo_ipk_) ,parameter :: NumGlobal_xy_planes = nz, Num_xy_points_per_plane = nx*ny + +contains + subroutine initialize_map(ictxt,NumMyElements,info) + integer(foo_ipk_) :: ictxt, NumMyElements, info + info = 0 + if (allocated(map)) deallocate(map,stat=info) + if (info == 0) allocate(map,stat=info) + if (info == 0) call foo_cdall(ictxt,map,info,nl=NumMyElements) + if (info == 0) call foo_cdasb(map,info) + end subroutine initialize_map + + function new_scalar_field(comm) result(this) + type(scalar_field) :: this + integer(foo_ipk_) ,intent(in) :: comm + real(foo_dpk_) ,allocatable :: f_v(:) + integer(foo_ipk_) :: i,j,k,NumMyElements, iam, np, info,ip + integer(foo_ipk_), allocatable :: idxs(:) + call foo_info(comm,iam,np) + NumMy_xy_planes = NumGlobal_xy_planes/np + NumMyElements = NumMy_xy_planes*Num_xy_points_per_plane + if (.not. allocated(map)) call initialize_map(comm,NumMyElements,info) + this%map => map + call foo_geall(this%f,this%map,info) + end function + + subroutine free(this) + class(scalar_field), intent(inout) :: this + integer(foo_ipk_) ::info + write(0,*) 'Freeing scalar_this%f' + call this%f%free() + end subroutine free + +end module foo_scalar_field_mod + +module foo_vector_field_mod + use foo_base_mod + use foo_scalar_field_mod, only : scalar_field,new_scalar_field + implicit none + type vector_field + type(scalar_field) :: u(1) + contains + procedure :: free + end type +contains + function new_vector_field(comm_in) result(this) + type(vector_field) :: this + integer(foo_ipk_), intent(in) :: comm_in + this%u = [new_scalar_field(comm_in)] ! Removing this line eliminates the memory leak + end function + + subroutine free(this) + class(vector_field), intent(inout) :: this + integer :: i + associate(vf=>this%u) + do i=1, size(vf) + write(0,*) 'Freeing vector_this%u(',i,')' + call vf(i)%free() + end do + end associate + end subroutine free + +end module foo_vector_field_mod + +program main + use foo_base_mod + use foo_vector_field_mod,only: vector_field,new_vector_field + use foo_scalar_field_mod,only: map + implicit none + type(vector_field) :: u + type(foo_d_vect_type) :: v + real(foo_dpk_), allocatable :: av(:) + integer(foo_ipk_) :: ictxt, iam, np, i,info + call foo_init(ictxt) + call foo_info(ictxt,iam,np) + u = new_vector_field(ictxt) + call u%free() + do i=1,10 + u = new_vector_field(ictxt) + call u%free() + end do + call u%free() + call foo_exit(ictxt) +end program