blob: cd1465e6abf8b9c95e2ff9dc42ca2f2f6e971649 [file] [log] [blame]
! { dg-do run }
!
! Test the fix for pr88735.
!
! Contributed by Martin Stein <mscfd@gmx.net>
!
module mod
implicit none
type, public :: t
integer, pointer :: i => NULL ()
character :: myname = 'z'
character :: alloc = 'n'
contains
procedure, public :: set
generic, public :: assignment(=) => set
final :: finalise
end type t
integer, public :: assoc_in_final = 0
integer, public :: calls_to_final = 0
character, public :: myname1, myname2
contains
subroutine set(self, x)
class(t), intent(out) :: self
class(t), intent(in) :: x
if (associated(self%i)) then
stop 1 ! Default init for INTENT(OUT)
endif
if (associated(x%i)) then
myname2 = self%myname
self%i => x%i
self%i = self%i + 1
end if
end subroutine set
subroutine finalise(self)
type(t), intent(inout) :: self
calls_to_final = calls_to_final + 1
myname1 = self%myname
if (associated(self%i)) then
assoc_in_final = assoc_in_final + 1
if (self%alloc .eq. 'y') deallocate (self%i)
end if
end subroutine finalise
end module mod
program finalise_assign
use mod
implicit none
type :: s
integer :: i = 0
type(t) :: x
end type s
type(s) :: a, b
type(t) :: c
a%x%myname = 'a'
b%x%myname = 'b'
c%myname = 'c'
allocate (a%x%i)
a%x%i = 123
a%x%alloc = 'y'
b = a
if (assoc_in_final /= 0) stop 2 ! b%x%i not associated before finalization
if (calls_to_final /= 2) stop 3 ! One finalization call
if (myname1 .ne. 'b') stop 4 ! Finalization before intent out become undefined
if (myname2 .ne. 'z') stop 5 ! Intent out now default initialized
if (.not.associated (b%x%i, a%x%i)) stop 6
allocate (c%i, source = 789)
c%alloc = 'y'
c = a%x
if (assoc_in_final /= 1) stop 6 ! c%i is allocated prior to the assignment
if (calls_to_final /= 3) stop 7 ! One finalization call for the assignment
if (myname1 .ne. 'c') stop 8 ! Finalization before intent out become undefined
if (myname2 .ne. 'z') stop 9 ! Intent out now default initialized
b = a
if (assoc_in_final /= 3) stop 10 ! b%i is associated by earlier assignment
if (calls_to_final /= 5) stop 11 ! One finalization call for the assignment
if (myname1 .ne. 'z') stop 12 ! b%x%myname was default initialized in earlier assignment
if (myname2 .ne. 'z') stop 13 ! Intent out now default initialized
if (b%x%i .ne. 126) stop 14 ! Three assignments with self%x%i pointing to same target
deallocate (a%x%i)
if (.not.associated (b%x%i, c%i)) then
stop 15 ! ditto
b%x%i =>NULL () ! Although not needed here, clean up
c%i => NULL ()
endif
end program finalise_assign