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] PR39295 - [4.2/4.3/4.4 Regression] Too strict interface conformance check


This one is straightforward - please look at the comments in the
testcase and the patch to interface.c

Bootstrapped and regtested on FC9/x86_64 - OK for trunk and 4.3?

Paul

2009-02-26  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/39292
	* interface.c (compare_type_rank_if): Return 1 if the symbols
	are the same and deal with external procedures where one is
	identified to be a function or subroutine by usage but the
	other is not.

2009-02-26  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/39292
	* gfortran.dg/interface_25.f90: New test.
	* gfortran.dg/interface_26.f90: New test.
Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c	(revision 144443)
+++ gcc/fortran/interface.c	(working copy)
@@ -491,17 +491,26 @@
   if (s1 == NULL || s2 == NULL)
     return s1 == s2 ? 1 : 0;
 
+  if (s1 == s2)
+    return 1;
+
   if (s1->attr.flavor != FL_PROCEDURE && s2->attr.flavor != FL_PROCEDURE)
     return compare_type_rank (s1, s2);
 
   if (s1->attr.flavor != FL_PROCEDURE || s2->attr.flavor != FL_PROCEDURE)
     return 0;
 
-  /* At this point, both symbols are procedures.  */
-  if ((s1->attr.function == 0 && s1->attr.subroutine == 0)
-      || (s2->attr.function == 0 && s2->attr.subroutine == 0))
-    return 0;
+  /* At this point, both symbols are procedures.  It can happen that
+     a external procedures are compared where one is identified by usage
+     to be a function or subroutine but the other is not.  Check TKR
+     nonetheless for these cases.  */
+  if (s1->attr.function == 0 && s1->attr.subroutine == 0)
+    return s1->attr.external == 1 ? compare_type_rank (s1, s2) : 0;
 
+  if (s2->attr.function == 0 && s2->attr.subroutine == 0)
+    return s2->attr.external == 1 ? compare_type_rank (s1, s2) : 0;
+
+  /* Now the type of procedure has been identified.  */
   if (s1->attr.function != s2->attr.function
       || s1->attr.subroutine != s2->attr.subroutine)
     return 0;
Index: gcc/testsuite/gfortran.dg/interface_25.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_25.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/interface_25.f90	(revision 0)
@@ -0,0 +1,45 @@
+! { dg-do compile }
+! Tests the fix for PR39295, in which the check of the interfaces
+! at lines 25 and 42 failed because opfunc1 is identified as a 
+! function by usage, whereas opfunc2 is not.
+!
+! Contributed by Jon Hurst <jhurst@ucar.edu>
+!
+MODULE  funcs
+CONTAINS
+  INTEGER FUNCTION test1(a,b,opfunc1) 
+    INTEGER :: a,b
+    INTEGER, EXTERNAL :: opfunc1
+    test1 = opfunc1( a, b ) 
+  END FUNCTION test1
+  INTEGER FUNCTION sumInts(a,b)
+    INTEGER :: a,b
+    sumInts = a + b
+  END FUNCTION sumInts
+END MODULE funcs
+
+PROGRAM test
+  USE funcs 
+  INTEGER :: rs
+  INTEGER, PARAMETER :: a = 2, b = 1
+  rs = recSum( a, b, test1, sumInts )
+  write(*,*) "Results", rs
+CONTAINS
+  RECURSIVE INTEGER FUNCTION recSum( a,b,UserFunction,UserOp ) RESULT( res )
+    IMPLICIT NONE
+    INTEGER :: a,b
+    INTERFACE 
+       INTEGER FUNCTION UserFunction(a,b,opfunc2) 
+         INTEGER :: a,b
+         INTEGER, EXTERNAL :: opfunc2
+       END FUNCTION UserFunction
+    END INTERFACE
+    INTEGER, EXTERNAL :: UserOp 
+
+    res = UserFunction( a,b, UserOp )
+
+    if( res .lt. 10 ) then
+       res = recSum( a, res, UserFunction, UserOp ) 
+    end if
+  END FUNCTION recSum
+END PROGRAM test
Index: gcc/testsuite/gfortran.dg/interface_26.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_26.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/interface_26.f90	(revision 0)
@@ -0,0 +1,46 @@
+! { dg-do compile }
+! Tests the fix for PR39295, in which the check of the interfaces
+! at lines 26 and 43 failed because opfunc1 is identified as a 
+! function by usage, whereas opfunc2 is not. This testcase checks
+! that TKR is stll OK in these cases.
+!
+! Contributed by Jon Hurst <jhurst@ucar.edu>
+!
+MODULE  funcs
+CONTAINS
+  INTEGER FUNCTION test1(a,b,opfunc1) 
+    INTEGER :: a,b
+    INTEGER, EXTERNAL :: opfunc1
+    test1 = opfunc1( a, b ) 
+  END FUNCTION test1
+  INTEGER FUNCTION sumInts(a,b)
+    INTEGER :: a,b
+    sumInts = a + b
+  END FUNCTION sumInts
+END MODULE funcs
+
+PROGRAM test
+  USE funcs 
+  INTEGER :: rs
+  INTEGER, PARAMETER :: a = 2, b = 1
+  rs = recSum( a, b, test1, sumInts ) ! { dg-error "Type/rank mismatch in argument" }
+  write(*,*) "Results", rs
+CONTAINS
+  RECURSIVE INTEGER FUNCTION recSum( a,b,UserFunction,UserOp ) RESULT( res )
+    IMPLICIT NONE
+    INTEGER :: a,b
+    INTERFACE 
+       INTEGER FUNCTION UserFunction(a,b,opfunc2) 
+         INTEGER :: a,b
+         REAL, EXTERNAL :: opfunc2
+       END FUNCTION UserFunction
+    END INTERFACE
+    INTEGER, EXTERNAL :: UserOp 
+
+    res = UserFunction( a,b, UserOp )
+
+    if( res .lt. 10 ) then
+       res = recSum( a, res, UserFunction, UserOp ) 
+    end if
+  END FUNCTION recSum
+END PROGRAM test

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