I actually only fill this to ensure my test case does not get lost. Fortran 2003 contains ("12.4 Procedure reference"): "C1229 (R1221) A procedure-name shall be the name of an external procedure, a dummy procedure, a module procedure, a procedure pointer, or a specific intrinsic function that is listed in 13.6 and not marked with a bullet(*). NOTE 12.16 -- This standard does not allow internal procedures to be used as actual arguments, in part to simplify the problem of ensuring that internal procedures with recursive hosts access entities from the correct instance (12.5.2.3) of the host." In Fortran 2008 (draft 07-007r3) this restriction is gone: "C1235 (R1223) A procedure-name shall be the name of an external, internal, module, or dummy procedure, a specific intrinsic function listed in 13.6 and not marked with a bullet (*), or a procedure pointer." Test program (initially created for PR 34133): ! { dg-do run } ! PR fortran/34133 ! ! Test of using internal bind(C) procedures as ! actual argument. Bind(c) on internal procedures and ! internal procedures are actual argument are ! Fortran 2008 (draft) extension. ! module test_mod use iso_c_binding implicit none contains subroutine test_sub(a, arg, res) interface subroutine a(x) bind(C) import integer(c_int), intent(inout) :: x end subroutine a end interface integer(c_int), intent(inout) :: arg integer(c_int), intent(in) :: res call a(arg) if(arg /= res) call abort() end subroutine test_sub subroutine test_func(a, arg, res) interface integer(c_int) function a(x) bind(C) import integer(c_int), intent(in) :: x end function a end interface integer(c_int), intent(in) :: arg integer(c_int), intent(in) :: res if(a(arg) /= res) call abort() end subroutine test_func end module test_mod program main use test_mod implicit none call test_sub (one, 33, 7*33) call test_func(two, 23, -123*23) contains subroutine one(x) bind(c) integer(c_int),intent(inout) :: x x = 7*x end subroutine one integer(c_int) function two(y) bind(c) integer(c_int),intent(in) :: y two = -123*y end function two end program main ! { dg-final { cleanup-modules "test_mod" } }
Some quotes from comp.lang.fortran to help with the implementation - or at least rise awareness of some problems. http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/eaa52a125f022287/ ------------- Steve Lionel writes: ----------------------------- The implementation is indeed not trivial and has to be different on each of the three operating systems we support, but it can be done. Note that the standard does say: NOTE 12.16 This standard does not allow internal procedures to be used as actual arguments, in part to simplify the problem of ensuring that internal procedures with recursive hosts access entities from the correct instance (12.5.2.3) of the host. If, as an extension, a processor allows internal procedures to be used as actual arguments, the correct instance in this case is the instance in which the procedure is supplied as an actual argument, even if the corresponding dummy argument is eventually invoked from a different instance. ------------- Steve Lionel writes then later: ------------------------ On Oct 25, 4:57 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote: > Does it have to be invoked from some instance of the containing > procedure? Traditionally, procedure names as actual arguments > were represented by the address of the procedure. In this case, > they have to also include a reference to the instance, mostly > the local variables, of the procedure. It has to be invoked while the containing procedure is active. You can't store it away somewhere and use it later. Once the containing procedure exits, the passed procedure "thing" becomes undefined (as of course do the local variables of the containing procedure.) A common implementation in the past was to write onto the stack a mini- routine that loads a register with the context (address of a frame pointer, etc.) and then calls the actual procedure. Now that operating systems (and processors) block execution of code from the stack, due to viruses taking advantage of this, other places are needed to store the code, but the concept is usually similar.
Asked at gcc-patches/fortran for suggestions how to implement this: http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00211.html
Subject: Bug 34162 Author: domob Date: Fri Sep 3 13:10:40 2010 New Revision: 163813 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=163813 Log: 2010-09-03 Daniel Kraft <d@domob.eu> PR fortran/34162 * resolve.c (resolve_actual_arglist): Allow internal procedure as actual argument with Fortran 2008. 2010-09-03 Daniel Kraft <d@domob.eu> PR fortran/34162 * gfortran.dg/internal_dummy_1.f90: Add -std=f2003. * gfortran.dg/internal_dummy_2.f08: New test. * gfortran.dg/internal_dummy_3.f08: New test. * gfortran.dg/internal_dummy_4.f08: New test. Added: trunk/gcc/testsuite/gfortran.dg/internal_dummy_2.f08 trunk/gcc/testsuite/gfortran.dg/internal_dummy_3.f08 trunk/gcc/testsuite/gfortran.dg/internal_dummy_4.f08 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/resolve.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/internal_dummy_1.f90
Fixed.