blob: a7683ae792e13c8e41e93d0a191e4988ff826241 [file] [log] [blame]
! { dg-do run }
!
! Test the fix for all three variants of PR82996, which used to
! segfault in the original testcase and ICE in the testcases of
! comments 1 and 2.
!
! Contributed by Neil Carlson <neil.n.carlson@gmail.com>
!
module mod0
integer :: final_count_foo = 0
integer :: final_count_bar = 0
end module mod0
!
! This is the original testcase, with a final routine 'foo' but
! but not in the container type 'bar1'.
!
module mod1
use mod0
private foo, foo_destroy
type foo
integer, pointer :: f(:) => null()
contains
final :: foo_destroy
end type
type bar1
type(foo) :: b(2)
end type
contains
impure elemental subroutine foo_destroy(this)
type(foo), intent(inout) :: this
final_count_foo = final_count_foo + 1
if (associated(this%f)) deallocate(this%f)
end subroutine
end module mod1
!
! Comment 1 was the same as original, except that the
! 'foo' finalizer is elemental and a 'bar' finalizer is added..
!
module mod2
use mod0
private foo, foo_destroy, bar_destroy
type foo
integer, pointer :: f(:) => null()
contains
final :: foo_destroy
end type
type bar2
type(foo) :: b(2)
contains
final :: bar_destroy
end type
contains
impure elemental subroutine foo_destroy(this)
type(foo), intent(inout) :: this
final_count_foo = final_count_foo + 1
if (associated(this%f)) deallocate(this%f)
end subroutine
subroutine bar_destroy(this)
type(bar2), intent(inout) :: this
final_count_bar = final_count_bar + 1
call foo_destroy(this%b)
end subroutine
end module mod2
!
! Comment 2 was the same as comment 1, except that the 'foo'
! finalizer is no longer elemental.
!
module mod3
use mod0
private foo, foo_destroy, bar_destroy
type foo
integer, pointer :: f(:) => null()
contains
final :: foo_destroy
end type
type bar3
type(foo) :: b(2)
contains
final :: bar_destroy
end type
contains
subroutine foo_destroy(this)
type(foo), intent(inout) :: this
final_count_foo = final_count_foo + 1
if (associated(this%f)) deallocate(this%f)
end subroutine
subroutine bar_destroy(this)
type(bar3), intent(inout) :: this
final_count_bar = final_count_bar + 1
do j = 1, size(this%b)
call foo_destroy(this%b(j))
end do
end subroutine
end module mod3
program main
use mod0
use mod1
use mod2
use mod3
type(bar1) :: x
type(bar2) :: y
type(bar3) :: z
call sub1(x)
if (final_count_foo /= 2) stop 1
if (final_count_bar /= 0) stop 2
call sub2(y)
if (final_count_foo /= 6) stop 3
if (final_count_bar /= 1) stop 4
call sub3(z)
if (final_count_foo /= 8) stop 5
if (final_count_bar /= 2) stop 6
contains
subroutine sub1(x)
type(bar1), intent(out) :: x
end subroutine
subroutine sub2(x)
type(bar2), intent(out) :: x
end subroutine
subroutine sub3(x)
type(bar3), intent(out) :: x
end subroutine
end program