(found when going through the link of PR gfortran rejects the following program where "gen" is both a generic and a specific procedure name as interface argument to PROCEDURE. I cannot find a reason why it should be invalid and thus I think it is valid. procedure(gen) :: f 1 Error: Interface 'gen' at (1) may not be generic module mod interface gen module procedure gen end interface gen contains pure subroutine gen(a) integer,intent(in) :: a end subroutine gen subroutine test(f) procedure(gen) :: f end subroutine test end module mod
The following program is also rejected, unless the marked line is removed/comment out. At a glance, it looks OK - and ifort, NAG f95 and g95 accept it. The error message is: print *, fun(enisoc, [0.0]) 1 Error: ELEMENTAL non-INTRINSIC procedure 'enisoc' is not allowed as an actual argument at (1) module cos_mod implicit none interface enisoc module procedure element, enisoc end interface enisoc contains pure function enisoc(x) real, intent(in) :: x(:) real enisoc(size(x)) enisoc = 2 end function enisoc elemental function element(x) real, intent(in) :: x real element element = cos(x) end function element end module cos_mod program main use cos_mod implicit none interface function fun(f,x) implicit none interface pure function f(x) real, intent(in) :: x(:) real f(size(x)) end function f end interface real x(:) real fun(size(x)) end function fun end interface print *, enisoc(0.0) ! <<< Works without this line print *, fun(enisoc, [0.0]) end program main !function fun(f,x) ! implicit none ! interface ! pure function f(x) ! real, intent(in) :: x(:) ! real f(size(x)) ! end function f ! end interface ! real x(:) ! real fun(size(f(x))) ! ! fun = f(x) !end function fun
(In reply to comment #1) > The following program is also rejected, unless the marked line is > removed/comment out. At a glance, it looks OK - and ifort, NAG f95 and g95 > accept it. The error message is: > > > print *, fun(enisoc, [0.0]) > 1 > Error: ELEMENTAL non-INTRINSIC procedure 'enisoc' is not allowed as an actual > argument at (1) This one I can not confirm. With a clean trunk at r155303 I do not see the error message on x86_64-unknown-linux-gnu.
(In reply to comment #0) > gfortran rejects the following program where "gen" is both a generic and a > specific procedure name as interface argument to PROCEDURE. I cannot find a > reason why it should be invalid and thus I think it is valid. > > > procedure(gen) :: f > 1 > Error: Interface 'gen' at (1) may not be generic The behavior in comment #0 I can confirm. And I agree that it is valid. Chapter 16.3.1 of F08 says: "Within its scope, a local identifier of one class shall not be the same as another local identifier of the same class, except that a generic name may be the same as the name of a procedure as explained in 12.4.3.4 [...]" In 12.4.3.4.1 we find: "A generic name is a generic identifier that refers to all of the procedure names in the interface block. A generic name may be the same as any one of the procedure names in the interface block, or the same as any accessible generic name."
cf. also PR 39427 (generic names can be the same as derived type names)
With gfortran 4.4.6, 4.5.3, 4.6.2, and trunk, the test in comment #0 gives the error while the test in comment #1 with the 'function fun(f,x)' block uncommented compiles and runs to give [macbook] f90/bug% a.out 1.00000000 2.00000000 with no error when run through valgrind.
The error in comment #0 should be fixable by something like the following: Index: gcc/fortran/decl.c =================================================================== --- gcc/fortran/decl.c (revision 189711) +++ gcc/fortran/decl.c (working copy) @@ -4807,9 +4807,17 @@ match_procedure_interface (gfc_symbol **proc_if) if ((*proc_if)->generic) { - gfc_error ("Interface '%s' at %C may not be generic", - (*proc_if)->name); - return MATCH_ERROR; + /* For generic interfaces, check if there is + a specific procedure with the same name. */ + gfc_interface *gen = (*proc_if)->generic; + while (gen && strcmp (gen->sym->name, (*proc_if)->name) != 0) + gen = gen->next; + if (!gen) + { + gfc_error ("Interface '%s' at %C may not be generic", + (*proc_if)->name); + return MATCH_ERROR; + } } if ((*proc_if)->attr.proc == PROC_ST_FUNCTION) { However, I wonder whether this whole generic check does not come to early. If the generic interface is declared after the PROCEDURE statement, it will not be triggered. It should probably be moved to resolve.c
(In reply to comment #6) > However, I wonder whether this whole generic check does not come to early. If > the generic interface is declared after the PROCEDURE statement, it will not be > triggered. It should probably be moved to resolve.c Along this line: module mod procedure(gen) :: f interface gen module procedure spec end interface gen contains subroutine spec() end subroutine end module This is rejected with: procedure(gen) :: f 1 Error: Interface 'gen' of procedure 'f' at (1) must be explicit I'm not sure if this error message is correct. In any case, it is accepted if 'spec' is used as an interface in the PROCEDURE declaration (which seems inconsistent).
Author: janus Date: Tue Jul 31 18:32:41 2012 New Revision: 190017 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=190017 Log: 2012-07-31 Janus Weil <janus@gcc.gnu.org> PR fortran/42418 * decl.c (match_procedure_interface): Move some checks to 'resolve_procedure_interface'. Set flavor if appropriate. * expr.c (gfc_check_pointer_assign): Cleanup of 'gfc_is_intrinsic'. * intrinsic.c (gfc_is_intrinsic): Additional checks for attributes which identify a procedure as being non-intrinsic. * resolve.c (resolve_procedure_interface): Checks moved here from 'match_procedure_interface'. Minor cleanup. (resolve_formal_arglist,resolve_symbol): Cleanup of 'resolve_procedure_interface' (resolve_actual_arglist,is_external_proc): Cleanup of 'gfc_is_intrinsic'. 2012-07-31 Janus Weil <janus@gcc.gnu.org> PR fortran/42418 * gfortran.dg/proc_decl_29.f90: New. Added: trunk/gcc/testsuite/gfortran.dg/proc_decl_29.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/decl.c trunk/gcc/fortran/expr.c trunk/gcc/fortran/intrinsic.c trunk/gcc/fortran/resolve.c trunk/gcc/testsuite/ChangeLog
Fixed with r190017. Closing.