https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89092

            Bug ID: 89092
           Summary: Host-associated generic used instead of use-associated
                    TBP in call
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: trnka at scm dot com
  Target Milestone: ---

GFortran rejects the following testcase because it only considers the
host-associated generic interface when resolving the call to y%Foo() instead of
the expected type-bound procedure. This dates back to GCC 5 at least.

       call y%Foo()
                  1
Error: There is no specific subroutine for the generic ‘foo’ at (1)

According to F2008 16.3.1, this should be valid Fortran, because TBPs belong to
a different class than generic interfaces, so they shouldn't clash. My
understanding of 12.5.6 is that the procedure-designator "Foo" should match the
corresponding specific TBP.

Intel Fortran accepts the testcase and gives the expected behaviour (the TBP is
called, printing "Foo(BType)").

I guess this could be related to PR 54035 or PR 57126, but I can't really tell
for sure.

module AModule
   implicit none
   private
   public Foo

   interface Foo
      module procedure FooPrivate
   end interface
contains
   subroutine FooPrivate(x)
      integer :: x

      write(*,*) 'Foo(integer)'
   end subroutine
end module
module BModule
   implicit none
   private

   type, public :: BType
   contains
      procedure :: Foo
   end type
contains
   subroutine Foo(self)
      class(BType) :: self

      write(*,*) 'Foo(BType)'
   end subroutine
end module
program iface_tbp_test
   use AModule
   implicit none

   call test()

contains
   subroutine test()
      use BModule

      type(BType) :: y

      call y%Foo()
   end subroutine
end program


Everything works as expected if the TBP binding is changed as follows:

   type, public :: BType
   contains
      procedure :: Foo => FooX
   end type
contains
   subroutine FooX(self)
      class(BType) :: self

      write(*,*) 'Foo(BType)'
   end subroutine

Reply via email to