https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88735

            Bug ID: 88735
           Summary: Nested assignment triggers call of final method for
                    right hand side
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mscfd at gmx dot net
  Target Milestone: ---

In the following code a type "t" is defined in module mod, which provides an
assignment method and a final routine. The program itself defines a type "s",
with a component of type "t". Assignment "b=a" should call the final method for
b%x, as procedure "set" has intent(out) for self. However, as can be seen from
the output, finalise is called for the right hand side (the intent(in)
argument). The set routine is called afterwards, surprisingly still thinks that
x%i is allocated (it has been wrongly deallocated within finalise). The value
however is somehow set to zero (looks like the deallocated memory zeroed?).

The problem does not occur with intent(inout) for argument "self" in procedure
"set", as finalise is not called at all. The problem does not occur if a and b
are of type t. The nested assignment via type s is necessary to trigger the
bug.


module mod

implicit none
private

type, public :: t
   integer, pointer :: i => null()

contains
   procedure, public :: set
   generic, public :: assignment(=) => set
   final :: finalise
end type t


contains

subroutine set(self, x)
   class(t), intent(out) :: self
   class(t), intent(in)  :: x
   if (associated(x%i)) then
      print *, 'setting: ', x%i
      self%i => x%i
      self%i = self%i + 1
   end if
end subroutine set


subroutine finalise(self)
   type(t), intent(inout) :: self
   if (associated(self%i)) then
      print *, 'finalising: ', self%i
      deallocate(self%i)
   end if
end subroutine finalise

end module mod


program finalise_assign
use mod
implicit none

type :: s
   type(t) :: x
end type s

type(s) :: a, b

allocate(a%x%i)
a%x%i = 123

b = a

end program finalise_assign

Reply via email to