Search code examples
fortranproceduregfortranderived-types

gfortran associates wrong type-bound procedure


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?


Solution

  • 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