https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122206
Bug ID: 122206
Summary: abstract interface, passing arguments by value to C
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: gavin.salam at physics dot ox.ac.uk
Target Milestone: ---
Passing arguments by value to C/C++ with an abstract interface: in a second
call to a given C++ routine, the arguments that are passed appear to be
corrupted.
Here's the Fortran
```
module test_example
use, intrinsic :: iso_c_binding
implicit none
integer, parameter :: dp = kind(1.0d0)
abstract interface
function simple_interface(iarg1, arg2, arg3, arg4) bind(C) result(res)
import c_double, c_int
integer(c_int), value, intent(in) :: iarg1
real(c_double), value, intent(in) :: arg2, arg3, arg4
real(c_double) :: res
end function
end interface
procedure(simple_interface), bind(C, name="simple_function" ) ::
simple_function
contains
subroutine test_example_interface
implicit none
real(c_double) :: arg2, arg3, arg4
character(len=*), parameter :: red=char(27)//"[31m", reset=char(27)//"[0m"
integer(c_int) :: iarg1
real(c_double) :: val1, val2
! Example values for testing
arg2 = 10._dp
arg3 = 3.0_dp
arg4 = 0.1_dp
! request coefficients relative to min_power (0 -> first non-zero term)
iarg1 = 2
val1 = simple_function(iarg1, arg2, arg3, arg4)
val2 = simple_function(iarg1, arg2, arg3, arg4)
if (val1 /= val2) then
print *, red//"mismatch between val1 and val2: ", val1, "/=", val2,reset
end if
end subroutine test_example_interface
end module test_example
program tester
use test_example
implicit none
call test_example_interface()
end program tester
```
and C++
```c++
#include <iostream>
extern "C" {
double simple_function(int iarg1, double arg2, double arg3, double arg4)
{
// Debug: print incoming arguments and the available range
std::cerr << "[debug] simple_function called: iarg1=" << iarg1
<< " arg2=" << arg2 << " arg3=" << arg3 << " arg4=" << arg4 <<
std::endl;
double val = static_cast<double>(iarg1) + arg2 + arg3 + arg4;
std::cerr << "[debug] simple_function returning: " << val << std::endl;
return(val);
}
}
```
The expected output is:
```
[debug] simple_function called: iarg1=2 arg2=10 arg3=3 arg4=0.1
[debug] simple_function returning: 15.1
[debug] simple_function called: iarg1=2 arg2=10 arg3=3 arg4=0.1
[debug] simple_function returning: 15.1
```
The actual output is
```
[debug] simple_function called: iarg1=2 arg2=10 arg3=3 arg4=0.1
[debug] simple_function returning: 15.1
[debug] simple_function called: iarg1=-362132780 arg2=15.1 arg3=1.38524e-309
arg4=8.25667e-317
[debug] simple_function returning: -3.62133e+08
mismatch between val1 and val2: 15.100000000000000 /=
-362132764.89999998
```
One sees that the arguments in the second call to simple_function are corrupted
(e.g. arg2 is -- incorrectly -- the return value of the first call).
We see this in 15.1 on MacOS 15.7.1 (with clang for the c++), on intel linux
with gfortran+gcc 11.4.0, on aarch64 linux (6.10.14-linuxkit) with gfortran+gcc
15.2.0.
To help with testing, the files are also at
https://github.com/gavinsalam/gfortran-15.2-arg-issue/
Report developed with Arnd Behring.