https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124652

            Bug ID: 124652
           Summary: passing a procedure pointer to c_funloc gives
                    incorrect result
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: damian at archaeologic dot codes
  Target Milestone: ---

$ gfortran --version
GNU Fortran (GCC) 16.0.1 20260309 (experimental)


$ cat proc_ptr_demo.f90 
program proc_ptr_demo
    use iso_c_binding
    implicit none

    ! Define an interface for the type of procedure we are pointing to
    abstract interface
        function compute_interface(x) result(res) bind(c)
            use iso_c_binding
            real(c_float), intent(in), value :: x
            real(c_float) :: res
        end function compute_interface
    end interface

    ! Procedure pointers
    procedure(compute_interface), pointer :: original_ptr => null()
    procedure(compute_interface), pointer :: restored_ptr => null()

    ! Point to our actual function
    original_ptr => square_it

    print *, "--- Procedure Pointer Round-trip Demo ---"

    ! Call the subroutine that performs the C conversion logic
    call round_trip_conversion(original_ptr, restored_ptr)

    ! Compare results
    if (associated(original_ptr, restored_ptr)) then
        print *, "Success: The restored pointer is associated with the
original."
    else
        print *, "Note: Compilers may not always report 'associated' as true "
        print *, "for proc pointers restored via C_F_PROCPOINTER, checking
output..."
    end if

    print *, "Original pointer result (5.0): ", original_ptr(5.0)
    print *, "Restored pointer result (5.0): ", restored_ptr(5.0)

contains

    subroutine round_trip_conversion(fptr_in, fptr_out)
        use iso_c_binding
        procedure(compute_interface), pointer, intent(in) :: fptr_in
        procedure(compute_interface), pointer, intent(out) :: fptr_out

        type(c_funptr) :: c_address

        ! 1. Get the C address of the Fortran procedure pointer
        c_address = c_funloc(fptr_in)

        ! 2. Convert that C address back into a Fortran procedure pointer
        call c_f_procpointer(c_address, fptr_out)
    end subroutine round_trip_conversion

    function square_it(x) result(res) bind(c)
        real(c_float), intent(in), value :: x
        real(c_float) :: res
        res = x * x
    end function square_it

end program

$ gfortran proc_ptr_demo.f90
$ ./a.out
--- Procedure Pointer Round-trip Demo ---
 Note: Compilers may not always report 'associated' as true 
 for proc pointers restored via C_F_PROCPOINTER, checking output...
 Original pointer result (5.0):    25.0000000    

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7f26b61d151f in ???
        at ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
#1  0x404060 in ???
Segmentation fault (core dumped)

Reply via email to