Description
Describe the issue:
Consider the following toy example:
! gh9693
module coddity
use, intrinsic :: iso_c_binding
implicit none
contains
function c_add(a, b) result(c) bind(c, name="c_add")
real(c_double) :: a, b
real(c_double) :: c
c = a + b
end function c_add
end module coddity
This, with python -m numpy.f2py -m buggy isoCfunc.f90
will produce the following wrapper:
! -*- f90 -*-
! This file is autogenerated with f2py (version:1.24.4)
! It contains Fortran 90 wrappers to fortran functions.
subroutine f2pywrap_coddity_c_add (c_addf2pywrap, a, e_b____result&
&___c____bind___c_er, e_name__c_add_er)
use coddity, only : c_add
real(kind=c_double) a
real e_b____result___c____bind___c_er
real e_name__c_add_er
real c_addf2pywrap
c_addf2pywrap = c_add(a, e_b____result___c____bind___c_er, e_name_&
&_c_add_er)
end subroutine f2pywrap_coddity_c_add
subroutine f2pyinitcoddity(f2pysetupfunc)
interface
subroutine f2pywrap_coddity_c_add (c_addf2pywrap, c_add, a, e_b___&
&_result___c____bind___c_er, e_name__c_add_er)
real c_add
real(kind=c_double) a
real e_b____result___c____bind___c_er
real e_name__c_add_er
real c_addf2pywrap
end subroutine f2pywrap_coddity_c_add
end interface
external f2pysetupfunc
call f2pysetupfunc(f2pywrap_coddity_c_add)
end subroutine f2pyinitcoddity
There is of course no end of problems with the generated wrapper as seen in the compiler errors below but also OTOH, kind
is not propagated, super mangled variable names..
For reference, note that without bind(c)
the wrapper is short and sweet:
! -*- f90 -*-
! This file is autogenerated with f2py (version:1.24.4)
! It contains Fortran 90 wrappers to fortran functions.
subroutine f2pywrap_coddity_c_add (c_addf2pywrap, a, b)
use coddity, only : c_add
real(kind=c_double) a
real(kind=c_double) b
real(kind=c_double) c_addf2pywrap
c_addf2pywrap = c_add(a, b)
end subroutine f2pywrap_coddity_c_add
subroutine f2pyinitcoddity(f2pysetupfunc)
interface
subroutine f2pywrap_coddity_c_add (c_addf2pywrap, c_add, a, b)
real(kind=c_double) c_add
real(kind=c_double) a
real(kind=c_double) b
real(kind=c_double) c_addf2pywrap
end subroutine f2pywrap_coddity_c_add
end interface
external f2pysetupfunc
call f2pysetupfunc(f2pywrap_coddity_c_add)
end subroutine f2pyinitcoddity
Note that the same function rewritten as a subroutine
correctly, that is for:
module coddity
use, intrinsic :: iso_c_binding, only: c_double
implicit none
contains
subroutine c_add(a, b, c) bind(c, name="c_add")
real(c_double), intent(in) :: a, b
real(c_double), intent(out) :: c
print*, "a is", a
print*, "b is", b
c = a + b
end subroutine c_add
end module coddity
With python -m numpy.f2py -m buggy isoCsub.f90
we have:
subroutine f2pyinitcoddity(f2pysetupfunc)
use coddity, only : c_add
external f2pysetupfunc
call f2pysetupfunc(c_add)
end subroutine f2pyinitcoddity
Though it won't compile correctly without an f2cmap
file, which is noted in #24555.
Reproduce the code example:
#NA
Error message:
INFO: gfortran:f90: /tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:8:16:
8 | real(kind=c_double) a
| 1
Error: Parameter ‘c_double’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:21:16:
21 | real(kind=c_double) a
| 1
Error: Parameter ‘c_double’ at (1) has not been declared or is a variable, which does not reduce to a constant expression
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:12:22:
12 | c_addf2pywrap = c_add(a, e_b____result___c____bind___c_er, e_name_&
| 1
Error: Type mismatch in argument ‘a’ at (1); passed REAL(4) to REAL(8)
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:12:22:
12 | c_addf2pywrap = c_add(a, e_b____result___c____bind___c_er, e_name_&
| 1
Error: Type mismatch in argument ‘b’ at (1); passed REAL(4) to REAL(8)
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:12:22:
12 | c_addf2pywrap = c_add(a, e_b____result___c____bind___c_er, e_name_&
| 1
Error: More actual than formal arguments in procedure call at (1)
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:12:22: Warning: Possible change of value in conversion from REAL(8) to REAL(4) at (1) [-Wconversion]
/tmp/tmpm7m0gs7h/src.linux-x86_64-3.8/buggy-f2pywrappers2.f90:5:39:
5 | subroutine f2pywrap_coddity_c_add (c_addf2pywrap, a, e_b____result&
| 1
......
18 | subroutine f2pywrap_coddity_c_add (c_addf2pywrap, c_add, a, e_b___&
| 2
Warning: 'f2pywrap_coddity_c_add' has the wrong number of arguments between (1) and (2)
Runtime information:
1.24.4
3.8.0 | packaged by conda-forge | (default, Nov 22 2019, 19:11:38)
[GCC 7.3.0]
Context for the issue:
This is likely to be broken right from the initial work on bind(c)
since it essentially is adding it to the name mangling process. Should be fixed and backported.