! { 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 ! 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