Bug: gfortran module procedures in submodules - interface defined in parent module

Paul Richard Thomas paul.richard.thomas@gmail.com
Tue Feb 7 11:36:00 GMT 2017


Hi Chris,

I can confirm that the bug is there on the latest 7.0.1. This is the
minimum testcase that exhibits the problem.

module mod
  interface myfun
    module function fun1(n) result(y)
      integer,  intent(in)    :: n
      real, dimension(n)  :: y
    end function fun1
  end interface myfun

end module mod

submodule (mod) submod
contains
  module procedure fun1

  end procedure fun1
end submodule

It appears that 'n' doesn't get treated as a dummy for reasons that I
do not see right now.

Bizarrely, this works perfectly and might be a good workaround for
you, omitting the 'source' part of the allocate, if you are assigning
to y somewhere else:

module mod
  interface myfun
    module function fun1(n) result(y)
      integer,  intent(in)    :: n
      real, allocatable, dimension(:)  :: y
    end function fun1
  end interface myfun

end module mod

submodule (mod) submod
contains
  module procedure fun1
    allocate (y(n), source = [(float(i), i = 1,n)])
  end procedure fun1
end submodule

  use mod
  print *, fun1(5)
end

I will post the PR if somebody hasn't got in there first.

Thanks

Paul

On 7 February 2017 at 03:26, Chris Coutinho <chrisbcoutinho@gmail.com> wrote:
> Hello Fortran/Gcc,
>
> I posted a potential bug onto comp.lang.fortran, and one poster suggested I
> send the bug to you directly to catch it sooner. Here is a copy of my post,
> including system information, version, and code snippet showing code.
>
> I would like to follow the progress on this bug if at all possible. Thanks
> in advance!
>
> Chris
>
> ---
>
> Hello comp.lang.fortran
>
> My request to create a new account on gcc bugzilla was denied, so I'm posti=
> ng this here as the next best option. Feel free to delete if inappropriate =
> - hopefully someone with more karma than me can see that it gets the right =
> attention.
>
> I'm trying to move the implementation of a procedure in my code out of its =
> module and into a submodule. To avoid writing and having to maintain the in=
> terface/dummy variables of the same routine in multiple places, I want to w=
> rite the interface in the module itself, and use `module procedures` within=
>  submodules. This is an option made aware to me by the wonderful fortranwik=
> i (http://fortranwiki.org/fortran/show/Submodules).
>
> Doing this works for dummy variables that have a 0-rank, but when trying to=
>  pass arrays between functions (either as input or output) I run into the f=
> ollowing compiler error:
>
>     internal compiler error: in gfc_get_symbol_decl, at fortran/trans-decl.=
> c:1423
>     Please submit a full bug report,
>     with preprocessed source if appropriate.
>
> I'm using gcc version 6.3.1 20170131 [gcc-6-branch revision 245058] (SUSE L=
> inux) on openSUSE Leap 42.2. I wrote a sample code snippet that reproduces =
> the bug on my machine (https://gist.github.com/cbcoutinho/cf22a60c971d4d4fa=
> 9330c064121ba18). Code reproduced below for convenience.
>
> The code snippet contains a module, a submodule, and a main program. The fu=
> nction interface is written in the module, and the implementation is writte=
> n in the submodule. This is supposed to represent how multiple implementati=
> ons could be written that are accessed according to their interfaces (i.e. =
> procedure overloading). In the submodule, there are two implementations of =
> the function. The first is just restating the module function interface, wh=
> ich compiles and runs as expected. The second option (currently commented o=
> ut), uses a module procedure, and produces the compiler error.
>
>
> --- Example Code ---
>
> module mod
>   use iso_fortran_env, only: wp=3D>real64
>   implicit none
>
>   private
>   public :: myfun
>   interface myfun
>     module function fun1(n, x) result(y)
>       integer,  intent(in)    :: n
>       real(wp), intent(in)    :: x
>       real(wp), dimension(n)  :: y
>     end function fun1
>   end interface myfun
>
> end module mod
>
> submodule (mod) submod
>   use iso_fortran_env, only: wp=3D>real64
>   implicit none
> contains
>
>   module function fun1(n, x) result(y)
>     integer,  intent(in)    :: n
>     real(wp), intent(in)    :: x
>     real(wp), dimension(n)  :: y
>
>     y =3D x * 2.d0
>
>   end function fun1
>
>   ! module procedure fun1
>   !
>   !   y =3D x * 2.d0
>   !
>   ! end procedure fun1
>
> end submodule submod
>
> program main
>   use mod, only: myfun
>   use iso_fortran_env, only: wp=3D>real64
>   implicit none
>
>   integer :: n =3D 2
>
>   print*, myfun(n, 1.d0)
>
> end program main
>
> --- End Example Code ---



-- 
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein



More information about the Fortran mailing list