Reputation: 155
consider the following small program that reproduces the segmentation fault I get with gfortran gcc 9.2.0 for mac os):
module stringmod
type :: str_t
character(len=:), allocatable :: s
contains
final :: finalize
end type str_t
type :: static_t
type(str_t) :: expr(3)
end type static_t
type :: dynamic_t
type(str_t), allocatable :: expr(:)
end type dynamic_t
contains
subroutine finalize ( x )
type(str_t), intent(in out) :: x
if (allocated(x%s)) deallocate(x%s)
end subroutine finalize
end module stringmod
use stringmod
implicit none
type(static_t ), allocatable :: stat(:)
type(dynamic_t), allocatable :: dyna(:)
integer :: i, j, n = 10
allocate(stat(n),dyna(n))
do i = 1, n
allocate(dyna(i)%expr(3))
end do
! No problem when deallocating "dyna":
deallocate(dyna)
! while deallocating "stat"causes a segfault with gfortran (gcc 9.2.0 for mac os)
! (unless the final method is removed from the DT):
deallocate(stat)
end
The segfault only occurs when deallocating the array of static_t type which has an explicit array member of str_t type. Strangely, it seems related to the final method of the str_t DT (when I remove this procedure, the problem goes away), but I don't see the reason.
Upvotes: 5
Views: 428
Reputation: 1
First I would comment, but I am not a common user so my rep isn't there. I have a strikingly similar problem and appreciate the precooked example which seems to work with gcc 5.4 accounting for this caveat:
Obviously this is not something you want to write code to, but wanted to relay my experiences and if you have submitted a bug report this could be useful info for them. I get the same behavior on my Ubuntu laptop with gcc 9.2.1.
Upvotes: 0
Reputation: 32366
This does look like a problem with final subroutines, after all removing the final subroutine takes the segmentation fault away. However, this is one example of a broader class of problem in gfortran.
For a problem in gfortran it is.
In your case, you have an available workaround: remove the final subroutine which is not actually invoked at any point. In more general cases this may not be an option. Either way, the thing to do is report this bug to the GCC maintainers (especially if you can test with later versions of the compiler).
Why do I say this part of a wider problem? Let's look at simplifying your code:
type :: str_t
character, allocatable :: s
end type str_t
type :: dynamic_t
type(str_t), allocatable :: expr
end type dynamic_t
type(dynamic_t), allocatable :: dyna
allocate(dyna)
allocate(dyna%expr)
end
or
implicit none
type :: str_t
character, allocatable :: s
end type str_t
type :: static_t
type(str_t) :: expr
end type static_t
type(static_t), allocatable :: stat
allocate(stat)
end
Neither has finalization to be seen, but both present (to me) segmentation faults when run.
If you want to see a connection between the program of the question and this answer: it is the deferred length nature of the component s
which is key. As an explicit-length (allocatable) scalar component the examples above crash with or without finalization; as a deferred length component finalization controls the crash.
Upvotes: 3