Bug 53956

Summary: [F03] PROCEDURE w/ interface: Bogus "EXTERNAL attribute conflicts with FUNCTION attribute"
Product: gcc Reporter: Tobias Burnus <burnus>
Component: fortranAssignee: janus
Status: RESOLVED FIXED    
Severity: normal CC: janus
Priority: P3 Keywords: rejects-valid
Version: 4.8.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2012-07-13 00:00:00

Description Tobias Burnus 2012-07-13 18:25:46 UTC
Found at comp.lang.fortran,
cf. http://www.rhinocerus.net/forum/lang-fortran/709699-sort-2d-matrix-2.html or https://groups.google.com/forum/?fromgroups#!topic/comp.lang.fortran/kfOR7y1bI0Q

The original example has been written by James Van Buskirk - see thread.

The following program gives the bogus error when the procedure pointer is invoked. Without procedure pointer or - for the dummy argument - using "procedure(integer)" instead of "integer, external" (which is semantically identically), works.

program testme
              1   
Error: EXTERNAL attribute conflicts with FUNCTION attribute in 'comparator2' at (1)


module m
contains
  function compare()
    integer :: compare
    compare = 42
  end function compare
  subroutine print_it(x)
    procedure(integer) :: x
    print *, x()
  end subroutine print_it
end module m

program testme
  use m
  implicit none
  interface
    subroutine sub(comparator2)        ! <<< related to those
      integer, external :: comparator2 ! <<< lines
    end subroutine sub
  end interface
  procedure(sub), pointer :: fp  ! << but the interface might be involved
  fp => print_it
  call fp (compare)   ! <<< Triggers the error
end program testme
Comment 1 janus 2012-07-13 18:57:44 UTC
Reduced test case:

  interface
    subroutine sub (c2)       
      integer, external :: c2 
    end subroutine
  end interface

  procedure(sub) :: fp

end
Comment 2 janus 2012-07-13 20:49:50 UTC
The error itself should be quite easy to fix. Here is a draft patch (not regtested yet):


Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 189470)
+++ gcc/fortran/resolve.c	(working copy)
@@ -10843,7 +10843,8 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag
 	  return FAILURE;
 	}
       if (sym->attr.external && sym->attr.function
-	  && ((sym->attr.if_source == IFSRC_DECL && !sym->attr.procedure)
+	  && ((sym->attr.if_source == IFSRC_DECL && !sym->attr.procedure
+	       && !sym->attr.dummy)
 	      || sym->attr.contained))
 	{
 	  gfc_error ("EXTERNAL attribute conflicts with FUNCTION attribute "



However, there seems to be an additional problem with the locus. Plus, I'm not sure why the error only occurs with the PROCEDURE statement.
Comment 3 janus 2012-07-14 13:01:22 UTC
(In reply to comment #2)
> Plus, I'm not
> sure why the error only occurs with the PROCEDURE statement.

Regarding the test case in comment #1, the difference between the c2-args of 'sub' and 'fp' is that the former has IFSRC_UNKNOWN, while the latter has IFSRC_DECL.

The latter symbol is created by 'gfc_copy_formal_args', and therefore an alternative (and probably preferable) patch would be:


Index: gcc/fortran/symbol.c
===================================================================
--- gcc/fortran/symbol.c	(revision 189470)
+++ gcc/fortran/symbol.c	(working copy)
@@ -4110,7 +4110,7 @@ gfc_copy_formal_args (gfc_symbol *dest, gfc_symbol
     }
 
   /* Add the interface to the symbol.  */
-  add_proc_interface (dest, IFSRC_DECL, head);
+  add_proc_interface (dest, src->attr.if_source, head);
 
   /* Store the formal namespace information.  */
   if (dest->formal != NULL)



> However, there seems to be an additional problem with the locus. 

... which is not a real problem, I guess (since the error message is fake anyway).
Comment 4 janus 2012-07-16 08:45:56 UTC
(In reply to comment #3)
> ... and therefore an
> alternative (and probably preferable) patch would be:

The patch in comment #3 generates the correct if_source for "c2", but a wrong one for "fp": Since it is just copied from "sub" it becomes IFSRC_IFBODY, but it should be IFSRC_DECL.
Comment 5 janus 2012-07-16 10:13:26 UTC
Author: janus
Date: Mon Jul 16 10:13:19 2012
New Revision: 189514

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=189514
Log:
2012-07-16  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/53956
	* gfortran.h (gfc_copy_formal_args,gfc_copy_formal_args_ppc): Modified
	prototypes.
	* symbol.c (gfc_copy_formal_args): New argument 'if_src'. Copy if_source
	of dummy procedures.
	(gfc_copy_formal_args_ppc): Ditto.
	* resolve.c (resolve_procedure_interface): Pass IFSRC_DECL to
	gfc_copy_formal_args.
	(resolve_fl_derived0): Pass IFSRC_DECL to gfc_copy_formal_args_ppc.


2012-07-16  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/53956
	* gfortran.dg/proc_decl_28.f90: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/proc_decl_28.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/symbol.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 janus 2012-07-16 10:17:37 UTC
Fixed with r189514. Closing.