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

            Bug ID: 88768
           Summary: Derived type io in conjunction with allocatable
                    component and recursion fails
           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: ---

This is a strange bug, which requires a some kind of dt IO (defined as "
generic :: write(unformatted) => write_unformatted", but not used!), an
allocatable component with dimension(:) (a "character(len=:), allocatable"
triggers the bug as well), and a recursive function.

If the "write(unformatted)"-part is commented out, the bug does not occur.
Without recursing, the return value is fine (variable y). Also, if the
dimension(:) is omitted in the declaration of r, then the bug disappears as
well.

The code either show funny values for z or segfaults. Valgrind shows an illegal
memory read.


module mod

implicit none
private

type, public :: t
   real, dimension(:), allocatable :: r
contains
   procedure :: set
   generic :: assignment(=) => set
   procedure :: recurse
   generic :: write(unformatted) => write_unformatted
   procedure :: write_unformatted
end type t

contains

subroutine set(self, x)
   class(t), intent(out) :: self
   class(t), intent(in) :: x
   real, dimension(:), allocatable :: tmp
   if (allocated(x%r)) then
      ! make a local copy to avoid any aliasing issues
      tmp = x%r
      self%r = tmp
   end if
end subroutine set

recursive function recurse(self, i) result(x)
   type(t) :: x
   class(t), intent(in) :: self
   integer,  intent(in) :: i
   if (i > 0) then
      x = self%recurse(i-1)
   else
      x = self
   end if
end function recurse

subroutine write_unformatted(dtv, unit, iostat, iomsg)
   class(t),         intent(in)    :: dtv
   integer,          intent(in)    :: unit
   integer,          intent(out)   :: iostat
   character(len=*), intent(inout) :: iomsg
   write(unit, iostat=iostat, iomsg=iomsg) 'unformatted'
end subroutine write_unformatted

end module mod


program dt_io

use mod
implicit none

type(t) :: x, y, z

x%r = [1.23, 2.21]
y = x%recurse(0)  ! fine
z = x%recurse(1)  ! fails

print *, x%r
print *, y%r
print *, z%r

end program dt_io

Reply via email to