Help working around finalization issue

I posted an example of an issue with the gfortran finalizer I’ve been scratching my head on:

This example has a derived type containing a hashmap:

type :: derived
   type(hash) :: map
end type

likely due to finalization issues (finalization being called onto a wrong memory address), memory gets corrupted and this causes all sorts of problems, when copying an entity:

type(derived) :: a,b
a = b ! CRASH

I’ve already been trying all sorts of workarounds including switching between pointer vs allocatables, and introducing user-defined final and assignment procedures, but so far I haven’t been lucky getting this to work with gfortran .

Because the crash happens accessing deallocated memory, I use magic numbers to manually store the allocation status, i.e.

integer(8) :: initialized = int(z'bbabababa') ! means "initialized"
integer(8) :: uninitialized = int(z'dededededf') means "uninitialized"

so among the 2^64 possible garbage values read by the finalization procedure, only two actually do represent valid allocation states, but this is apparently not enough in this case.

So I was wondering if any of the Fortran gurus here on Discourse has experience implementing practical workarounds for this type of nested derived types, and if there are guidelines that should be followed to avoid this… it would be very appreciated :slight_smile:

Can you cut your example down to something minimal that reproduces the crash? Ideally where nothing else can be deleted. It’s difficult to investigate 1.6k lines :slight_smile:

1 Like

Agreed! this is a significantly reduced version:

Note that I’ve just found a combination that works:

  • use only allocatables
  • do not finalize structures with an allocatable recursive component:
! newly found gfortran ICE
module crash
   type :: t
      type(t), allocatable :: x
      contains
      final :: t_final ! no crash if no final
   end type
   contains
   subroutine t_final(this)
       type(t), intent(inout) :: this
   end subroutine t_final
end module crash
program p
   use crash
end          

… and here is a neat implementation of the <int,int> unordered map with all pure and `elemental procedures :slight_smile: