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