When we compile (gfortran 5.3 or 7.2) and run the following code, line 9 of the main.f03 ends up in a subroutine that is never called. Can anyone explain why?
main.f03:
program main
use minimalisticcase
implicit none
type(DataStructure) :: data_structure
type(DataLogger) :: data_logger
call data_structure%init()
call data_logger%init(data_structure)
end program
minimalisticcase.f03:
module minimalisticcase
implicit none
type, public :: DataStructure
integer :: i
contains
procedure, pass :: init => init_data_structure
procedure, pass :: a => beginning_of_alphabet
end type
type, public :: DataLogger
type(DataStructure), pointer :: data_structure
contains
procedure, pass :: init => init_data_logger
procedure, pass :: do_something => do_something
end type
contains
subroutine init_data_structure(self)
implicit none
class(DataStructure), intent(inout) :: self
write(*,*) 'init_data_structure'
end subroutine
subroutine beginning_of_alphabet(self)
implicit none
class(DataStructure), intent(inout) :: self
write(*,*) 'beginning_of_alphabet'
end subroutine
subroutine init_data_logger(self, data_structure)
implicit none
class(DataLogger), intent(inout) :: self
class(DataStructure), target :: data_structure
write(*,*) 'init_data_logger'
self%data_structure => data_structure
call self%do_something()
end subroutine
subroutine do_something(self)
implicit none
class(DataLogger), intent(inout) :: self
write(*,*) 'do_something'
end subroutine
end module
On line 40 of 'minimalisticcase.f03' we call 'do_something' of the DataLogger. But instead the 'beginning_of_alphabet' subroutin of DataStructure is executed!
Apparently one can fix this by changing line 13 in 'minimalisticcase.f03' from type(DataStructure), pointer :: data_structure
to class(DataStructure), pointer :: data_structure
.
But why?
This is a bug in gfortran. I posted it on Bugzilla as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82312. The error is now fixed on the GCC trunk.
A temporary workaround is to encase the pointer assignment in a select type, thusly:
select type (data_structure)
type is (DataStructure)
self%data_structure => data_structure
end select