http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59560
--- Comment #11 from klaas_giesbertz at hotmail dot com --- Finally figured out how to make it work. I guess this is what the class(*) is useful for. Using class(*) I can simply overload Func and its resolution becomes dynamic. I consider the class(*) quite an overkill, but it works. So the Base and Derived Modules now become module BaseModule implicit none private type, public :: BaseClass contains procedure :: Func end type contains subroutine Func(self, other) class(BaseClass), intent(inout) :: self class(*), intent(in) :: other write(*,*) 'Base Func called' end subroutine end module module DerivedModule use BaseModule implicit none private type, public, extends(BaseClass) :: DerivedClass real :: x contains procedure :: Func end type contains subroutine Func(self, other) class(DerivedClass), intent(inout) :: self class(*), intent(in) :: other write(*,*) 'Derived Func called' select type(bla => other) class is (DerivedClass) write(*,*) 'DerivedClass found' class default write(*,*) 'Bad luck' end select end subroutine end module