This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, fortran] PR40443 - Elemental procedure in generic interface incorrectly selected in preference to specific procedure


Dear All,

I thought that this one would be a tough nut to crack but it turns out
not to be the case.  14.1.2.4.1 requires that an elemental match to a
reference has lower precedence than any other correct match that there
might be.  This is easily implemented in the attached patch by holding
back an elemental match until nothing else is found. The testcase is
the reporter's.

Bootstrapped and regtested on FC9/x86_64

OK for trunk and.... ?? I would suggest 4.4 and maybe even 4.3.

Paul

2009-06-21  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/40443
	* interface.c (gfc_search_interface): Hold back a match to an
	elementary procedure until all other possibilities are
	exhausted.

2009-06-21  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/40443
	* gfortran.dg/generic_18.f90: New test.
Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c	(revision 148730)
+++ gcc/fortran/interface.c	(working copy)
@@ -2417,6 +2417,7 @@
 gfc_search_interface (gfc_interface *intr, int sub_flag,
 		      gfc_actual_arglist **ap)
 {
+  gfc_symbol *elem_sym = NULL;
   for (; intr; intr = intr->next)
     {
       if (sub_flag && intr->sym->attr.function)
@@ -2425,10 +2426,19 @@
 	continue;
 
       if (gfc_arglist_matches_symbol (ap, intr->sym))
-	return intr->sym;
+	{
+	  /* Satisfy 12.4.4.1 such that an elemental match has lower
+	     weight than a non-elemental match.  */ 
+	  if (intr->sym->attr.elemental)
+	    {
+	      elem_sym = intr->sym;
+	      continue;
+	    }
+	  return intr->sym;
+	}
     }
 
-  return NULL;
+  return elem_sym ? elem_sym : NULL;
 }
 
 
Index: gcc/testsuite/gfortran.dg/generic_18.f90
===================================================================
--- gcc/testsuite/gfortran.dg/generic_18.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/generic_18.f90	(revision 0)
@@ -0,0 +1,54 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! Test the fix for PR40443 in which the final call to the generic
+! 'SpecElem' was resolved to the elemental rather than the specific
+! procedure, which is required by the second part of 12.4.4.1.
+!
+! Contributed by Ian Harvey <ian_harvey@bigpond.com>
+!
+MODULE SomeOptions
+  IMPLICIT NONE  
+  INTERFACE ElemSpec
+    MODULE PROCEDURE ElemProc
+    MODULE PROCEDURE SpecProc
+  END INTERFACE ElemSpec  
+  INTERFACE SpecElem
+    MODULE PROCEDURE SpecProc
+    MODULE PROCEDURE ElemProc
+  END INTERFACE SpecElem
+CONTAINS
+  ELEMENTAL SUBROUTINE ElemProc(a)  
+    CHARACTER, INTENT(OUT) :: a
+    !****
+    a = 'E'            
+  END SUBROUTINE ElemProc
+
+  SUBROUTINE SpecProc(a)  
+    CHARACTER, INTENT(OUT) :: a(:)
+    !****    
+    a = 'S'    
+  END SUBROUTINE SpecProc
+END MODULE SomeOptions
+
+PROGRAM MakeAChoice
+  USE SomeOptions  
+  IMPLICIT NONE
+  CHARACTER scalar, array(2)    
+  !****
+  CALL ElemSpec(scalar) ! Should choose the elemental (and does)
+  WRITE (*, 100) scalar
+  CALL ElemSpec(array)  ! Should choose the specific (and does)
+  WRITE (*, 100) array
+  !----
+  CALL SpecElem(scalar) ! Should choose the elemental (and does)
+  WRITE (*, 100) scalar
+  CALL SpecElem(array)  ! Should choose the specific (but didn't)
+  WRITE (*, 100) array  
+  !----
+  100 FORMAT(A,:,', ',A)
+END PROGRAM MakeAChoice
+! { dg-final { scan-tree-dump-times "specproc" 3 "original" } }
+! { dg-final { scan-tree-dump-times "elemproc" 3 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
+! { dg-final { cleanup-modules "SomeOptions" } }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]