https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84674
Libavius <daraja at web dot de> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |daraja at web dot de --- Comment #4 from Libavius <daraja at web dot de> --- I got a bug, which I think is related to the one described here and wanted to avoid opening another bug report. I tried my best to build a small minimal example (see bottom). It compiles with all compilers I tried. However with gfortran 6.3.1, gfortran 7.3.1 and gfortran 8.1.0 it does not produce the wanted result (see test.f90). With gfortran 4.8.5, nag 6.2 and intel 18.0.3 it runs as expected. I carried out all tests on CentOS 7.4 and Ubuntu 16.04. With a debugger, I could see: in test.f90, F%get() is called (line 8), the program then moves into child_get() in module2.f90 (line 35) as it should. However, stepping into this%calc() (line 39), it moves to child_reset() in module1.f90 (line 31) instead of child2_calc() in module2.f90 (line 15). There are two ways to get this program to work, which are both quite weird: 1. remove "non_overridable" from line 14 in module1.f90 old: procedure, pass, non_overridable :: get => child_get new: procedure, pass :: get => child_get 2. merge module1 and module2 into one module. FILES: ***module1.f90: module module1 implicit none private public :: child type, abstract :: parent contains procedure, pass :: reset => parent_reset end type parent type, extends(parent), abstract :: child contains procedure, pass, non_overridable :: reset => child_reset procedure, pass, non_overridable :: get => child_get procedure(calc_i), pass, deferred :: calc end type child abstract interface pure function calc_i(this) result(value) import :: child class(child), intent(in) :: this integer :: value end function calc_i end interface contains pure subroutine parent_reset(this) class(parent), intent(inout) :: this end subroutine parent_reset pure subroutine child_reset(this) class(child), intent(inout) :: this end subroutine child_reset function child_get(this) result(value) class(child), intent(inout) :: this integer :: value value = this%calc() end function child_get end module module1 ***module2.f90: module module2 use module1, only: child implicit none private public :: child2 type, extends(child) :: child2 contains procedure, pass :: calc => child2_calc end type child2 contains pure function child2_calc(this) result(value) class(child2), intent(in) :: this integer :: value value = 1 end function child2_calc end module module2 ***test.f90: program test use module2, only: child2 implicit none type(child2) :: F if (F%get() /= 1) stop ': FAILED' end program test