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

            Bug ID: 69563
           Summary: Generic TBP incorrectly resolves to elemental
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: neil.n.carlson at gmail dot com
  Target Milestone: ---

In the following example program the call to X%SUB should resolve to SUB_ARRAY,
but instead the compiler tries to resolve it to the elemental SUB_ELEM, but
then emits an error (as it must) because the the THIS argument is not also an
array:

gfortran-bug-20160129.f90:46:8:

   call x%sub ([1,2])
        1

Error: Actual argument at (1) for INTENT(INOUT) dummy ‘this’ of ELEMENTAL
subroutine ‘sub_elem’ is a scalar, but another actual argument is an array

Here's the code:

module a_type

  type :: a
    integer :: n
  contains
    procedure :: sub_elem
    procedure :: sub_array
    generic :: sub => sub_elem, sub_array
  end type

contains

  elemental subroutine sub_elem (this, arg)
    class(a), intent(inout) :: this
    integer, intent(in) :: arg
    this%n = arg
  end subroutine

  subroutine sub_array (this, arg)
    class(a), intent(inout) :: this
    integer, intent(in) :: arg(:)
    this%n = sum(arg)
  end subroutine

end module

program main

  use a_type
  type(a) :: x, y(2)

  call x%sub ([1,2])
  call y%sub ([1,2])

  print *, x%n, '(expect 3)'
  print *, y%n, '(expect 1 2)'

end program

Interestingly, this similar example, where the generic is not TB, compiles and
runs as expected:

module foo
  interface sub
    module procedure sub_elem, sub_array
  end interface
contains
  elemental subroutine sub_elem (a, b)
    integer, intent(out) :: a
    integer, intent(in)  :: b
    a = b
  end subroutine
  subroutine sub_array (a, b)
    integer, intent(out) :: a
    integer, intent(in)  :: b(:)
    a = sum(b)
  end subroutine
end module

program main
  use foo
  integer x, y(2)
  call sub (x, [1,2])
  call sub (y, [1,2])
  print *, x, '(expect 3)'
  print *, y, '(expect 1 2)'
end

Reply via email to