-
-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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 coddityThis, 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 f2pyinitcoddityThere 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 f2pyinitcoddityNote 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 coddityWith 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 f2pyinitcoddityThough it won't compile correctly without an f2cmap file, which is noted in #24555.
Reproduce the code example:
#NAError 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.