diff mbox

PR fortran/77406

Message ID 20160901001443.GA65237@troutmask.apl.washington.edu
State New
Headers show

Commit Message

Steve Kargl Sept. 1, 2016, 12:14 a.m. UTC
Consider the code

   interface s
      subroutine foo(*)
      end subroutine foo
      subroutine bar(*)
      end subroutine bar
   end interface s
   end

gfortran currently ICE's, because she is ill-prepared
to deal with alternate returns in an interface blocks.
The attached patch fixes this problem.


While I was fixing the problem I took this opportunity
to improve the error reporting.  Consider the code

   interface s
      subroutine foo(i)
      end subroutine foo
      subroutine bar(j)
      end subroutine bar
   end interface s
   end

gfortran currently reports

% gfc6 a.f90
a.f90:7:21:

    end subroutine bar
                     1
Error: Ambiguous interfaces 'bar' and 'foo' in generic interface 's' at (1)

The (IMNSHO) improved error messages is now

% gfc7 -c a.f90
a.f90:3:17:

    subroutine foo(i)
                 1
a.f90:6:17:

    subroutine bar(j)
                 2
Error: Ambiguous interfaces in generic interface 's' for 'foo' at (1) and 'bar' at (2)

OK to commit on Saturday?


2016-09-03  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/77406
	* interface.c (gfc_compare_interfaces): Fix detection of ambiguous
	interface involving alternate return.
	(check_interface1): Improve error message and loci.

2016-09-03  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/77406
	* gfortran.dg/pr77406.f90: New test.
	* gfortran.dg/assumed_type_3.f90: Update error messages.
	* gfortran.dg/defined_operators_1.f90: Ditto.
	* gfortran.dg/generic_26.f90: Ditto.
	* gfortran.dg/generic_7.f90: Ditto.
	* gfortran.dg/gomp/udr5.f90: Ditto.
	* gfortran.dg/gomp/udr7.f90: Ditto.
	* gfortran.dg/interface_1.f90: Ditto.
	* gfortran.dg/interface_37.f90: Ditto.
	* gfortran.dg/interface_5.f90: Ditto.
	* gfortran.dg/interface_6.f90: Ditto.
	* gfortran.dg/interface_7.f90
	* gfortran.dg/no_arg_check_3.f90
	* gfortran.dg/operator_5.f90
	* gfortran.dg/proc_ptr_comp_20.f90: Ditto.

Comments

Steve Kargl Sept. 9, 2016, 6:25 p.m. UTC | #1
On Wed, Aug 31, 2016 at 05:14:43PM -0700, Steve Kargl wrote:
> 
> 2016-09-03  Steven G. Kargl  <kargl@gcc.gnu.org>
> 
> 	PR fortran/77406
> 	* interface.c (gfc_compare_interfaces): Fix detection of ambiguous
> 	interface involving alternate return.
> 	(check_interface1): Improve error message and loci.
> 
> 2016-09-03  Steven G. Kargl  <kargl@gcc.gnu.org>
> 
> 	PR fortran/77406
> 	* gfortran.dg/pr77406.f90: New test.
> 	* gfortran.dg/assumed_type_3.f90: Update error messages.
> 	* gfortran.dg/defined_operators_1.f90: Ditto.
> 	* gfortran.dg/generic_26.f90: Ditto.
> 	* gfortran.dg/generic_7.f90: Ditto.
> 	* gfortran.dg/gomp/udr5.f90: Ditto.
> 	* gfortran.dg/gomp/udr7.f90: Ditto.
> 	* gfortran.dg/interface_1.f90: Ditto.
> 	* gfortran.dg/interface_37.f90: Ditto.
> 	* gfortran.dg/interface_5.f90: Ditto.
> 	* gfortran.dg/interface_6.f90: Ditto.
> 	* gfortran.dg/interface_7.f90
> 	* gfortran.dg/no_arg_check_3.f90
> 	* gfortran.dg/operator_5.f90
> 	* gfortran.dg/proc_ptr_comp_20.f90: Ditto.
> 

Ping.  OK to commit.
diff mbox

Patch

Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c	(revision 239833)
+++ gcc/fortran/interface.c	(working copy)
@@ -1616,14 +1616,23 @@  gfc_compare_interfaces (gfc_symbol *s1, 
   f1 = gfc_sym_get_dummy_args (s1);
   f2 = gfc_sym_get_dummy_args (s2);
 
+  /* Special case: No arguments.  */
   if (f1 == NULL && f2 == NULL)
-    return 1;			/* Special case: No arguments.  */
+    return 1;
 
   if (generic_flag)
     {
       if (count_types_test (f1, f2, p1, p2)
 	  || count_types_test (f2, f1, p2, p1))
 	return 0;
+
+      /* Special case: alternate returns.  If both f1->sym and f2->sym are
+	 NULL, then the leading formal arguments are alternate returns.  
+	 The previous conditional should catch argument lists with 
+	 different number of argument.  */
+      if (f1 && f1->sym == NULL && f2 && f2->sym == NULL)
+	return 1;
+
       if (generic_correspondence (f1, f2, p1, p2)
 	  || generic_correspondence (f2, f1, p2, p1))
 	return 0;
@@ -1791,13 +1800,15 @@  check_interface1 (gfc_interface *p, gfc_
 				       generic_flag, 0, NULL, 0, NULL, NULL))
 	  {
 	    if (referenced)
-	      gfc_error ("Ambiguous interfaces %qs and %qs in %s at %L",
-			 p->sym->name, q->sym->name, interface_name,
-			 &p->where);
+	      gfc_error ("Ambiguous interfaces in %s for %qs at %L "
+			 "and %qs at %L", interface_name,
+			 q->sym->name, &q->sym->declared_at,
+			 p->sym->name, &p->sym->declared_at);
 	    else if (!p->sym->attr.use_assoc && q->sym->attr.use_assoc)
-	      gfc_warning (0, "Ambiguous interfaces %qs and %qs in %s at %L",
-			   p->sym->name, q->sym->name, interface_name,
-			   &p->where);
+	      gfc_warning (0, "Ambiguous interfaces in %s for %qs at %L "
+			 "and %qs at %L", interface_name,
+			 q->sym->name, &q->sym->declared_at,
+			 p->sym->name, &p->sym->declared_at);
 	    else
 	      gfc_warning (0, "Although not referenced, %qs has ambiguous "
 			   "interfaces at %L", interface_name, &p->where);
Index: gcc/testsuite/gfortran.dg/assumed_type_3.f90
===================================================================
--- gcc/testsuite/gfortran.dg/assumed_type_3.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/assumed_type_3.f90	(working copy)
@@ -66,12 +66,12 @@  subroutine nine()
     end subroutine okok2
   end interface
   interface three
-    subroutine ambig1(x)
+    subroutine ambig1(x) ! { dg-error "Ambiguous interfaces" }
       type(*) :: x
     end subroutine ambig1
-    subroutine ambig2(x)
+    subroutine ambig2(x) ! { dg-error "Ambiguous interfaces" }
       integer :: x
-    end subroutine ambig2 ! { dg-error "Ambiguous interfaces 'ambig2' and 'ambig1' in generic interface 'three'" }
+    end subroutine ambig2
   end interface
 end subroutine nine
 
Index: gcc/testsuite/gfortran.dg/defined_operators_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/defined_operators_1.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/defined_operators_1.f90	(working copy)
@@ -11,7 +11,7 @@  module mymod
      module procedure foo_1
      module procedure foo_2
      module procedure foo_3
-     module procedure foo_1_OK  ! { dg-error "Ambiguous interfaces" }
+     module procedure foo_1_OK
      module procedure foo_2_OK
      function foo_chr (chr) ! { dg-error "cannot be assumed character length" }
        character(*) :: foo_chr
@@ -37,12 +37,12 @@  contains
     integer :: foo_1
     foo_0 = 1
   end function foo_0
-  function foo_1 (a) ! { dg-error "must be INTENT" }
+  function foo_1 (a) ! { dg-error "Ambiguous interfaces" }
     integer :: foo_1
-    integer :: a
+    integer, intent(in) :: a
     foo_1 = 1
   end function foo_1
-  function foo_1_OK (a)
+  function foo_1_OK (a) ! { dg-error "Ambiguous interfaces" }
     integer :: foo_1_OK
     integer, intent (in) :: a
     foo_1_OK = 1
@@ -65,3 +65,4 @@  contains
     foo_3 = a + 3 * b - c
   end function foo_3
 end module mymod
+
Index: gcc/testsuite/gfortran.dg/generic_26.f90
===================================================================
--- gcc/testsuite/gfortran.dg/generic_26.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/generic_26.f90	(working copy)
@@ -9,17 +9,17 @@  module a
 
   interface test
     procedure testAlloc
-    procedure testPtr   ! { dg-error "Ambiguous interfaces" }
+    procedure testPtr
   end interface
 
 contains
 
-  logical function testAlloc(obj)
+  logical function testAlloc(obj)    ! { dg-error "Ambiguous interfaces" }
     integer, allocatable :: obj
     testAlloc = .true.
   end function
   
-  logical function testPtr(obj)
+  logical function testPtr(obj)      ! { dg-error "Ambiguous interfaces" }
     integer, pointer :: obj
     testPtr = .false.
   end function
Index: gcc/testsuite/gfortran.dg/generic_7.f90
===================================================================
--- gcc/testsuite/gfortran.dg/generic_7.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/generic_7.f90	(working copy)
@@ -7,15 +7,15 @@ 
 MODULE global
 INTERFACE iface
   MODULE PROCEDURE sub_a
-  MODULE PROCEDURE sub_b ! { dg-error "Ambiguous interfaces" }
+  MODULE PROCEDURE sub_b
   MODULE PROCEDURE sub_c
 END INTERFACE
 CONTAINS
-  SUBROUTINE sub_a(x)
+  SUBROUTINE sub_a(x) ! { dg-error "Ambiguous interfaces" }
     INTEGER, INTENT(in) :: x
     WRITE (*,*) 'A: ', x
   END SUBROUTINE
-  SUBROUTINE sub_b(y)
+  SUBROUTINE sub_b(y) ! { dg-error "Ambiguous interfaces" }
     INTEGER, INTENT(in) :: y
     WRITE (*,*) 'B: ', y
   END SUBROUTINE
Index: gcc/testsuite/gfortran.dg/gomp/udr5.f90
===================================================================
--- gcc/testsuite/gfortran.dg/gomp/udr5.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/gomp/udr5.f90	(working copy)
@@ -55,5 +55,5 @@  subroutine f1
 end subroutine f1
 subroutine f2
   use udr5m3	! { dg-error "Previous !.OMP DECLARE REDUCTION|Ambiguous interfaces" }
-  use udr5m2	! { dg-error "Ambiguous !.OMP DECLARE REDUCTION" }
+  use udr5m2	! { dg-error "Ambiguous !.OMP DECLARE REDUCTION|Ambiguous interfaces" }
 end subroutine f2
Index: gcc/testsuite/gfortran.dg/gomp/udr7.f90
===================================================================
--- gcc/testsuite/gfortran.dg/gomp/udr7.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/gomp/udr7.f90	(working copy)
@@ -78,7 +78,7 @@  subroutine f1
 end subroutine f1
 subroutine f2
   use udr7m3	! { dg-error "Previous !.OMP DECLARE REDUCTION|Ambiguous interfaces" }
-  use udr7m2	! { dg-error "Ambiguous !.OMP DECLARE REDUCTION" }
+  use udr7m2	! { dg-error "Ambiguous !.OMP DECLARE REDUCTION|Ambiguous interfaces" }
 end subroutine f2
 subroutine f3
   use udr7m4
Index: gcc/testsuite/gfortran.dg/interface_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_1.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/interface_1.f90	(working copy)
@@ -24,15 +24,15 @@  end module y
 
 module z
 
-  use y
+  use y    ! { dg-warning "in generic interface" }
 
   interface ambiguous
-    module procedure f    ! { dg-warning "in generic interface" "" }
+    module procedure f 
   end interface
 
   contains
 
-    real function f(a)
+    real function f(a)   ! { dg-warning "in generic interface" "" }
       real a
       f = a
     end function
Index: gcc/testsuite/gfortran.dg/interface_37.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_37.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/interface_37.f90	(working copy)
@@ -4,13 +4,13 @@ 
 ! Subroutine/function ambiguity in generics.
 !
      interface q
-       subroutine qr(f)
+       subroutine qr(f)  ! { dg-error "Ambiguous interfaces" }
          implicit real(f)
          external f
        end subroutine
-       subroutine qc(f)
+       subroutine qc(f)  ! { dg-error "Ambiguous interfaces" }
          implicit complex(f)
          external f
-       end subroutine ! { dg-error "Ambiguous interfaces" }
+       end subroutine
      end interface q
    end
Index: gcc/testsuite/gfortran.dg/interface_5.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_5.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/interface_5.f90	(working copy)
@@ -46,8 +46,8 @@  subroutine i_am_ok
 end subroutine i_am_ok
 
 program main
-  USE f77_blas_extra ! { dg-error "Ambiguous interfaces" }
-  USE f77_blas_generic
+  USE f77_blas_extra   ! { dg-error "Ambiguous interfaces" }
+  USE f77_blas_generic ! { dg-error "Ambiguous interfaces" }
   character(6) :: chr
   chr = ""
   call bl_copy(1.0, chr)
Index: gcc/testsuite/gfortran.dg/interface_6.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_6.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/interface_6.f90	(working copy)
@@ -7,16 +7,16 @@ 
 ! procedures below are invalid, even though actually unambiguous.
 !
 INTERFACE BAD8
-  SUBROUTINE S8A(X,Y,Z)
+  SUBROUTINE S8A(X,Y,Z)     ! { dg-error "Ambiguous interfaces" }
     REAL,OPTIONAL :: X
     INTEGER :: Y
     REAL :: Z
   END SUBROUTINE S8A
-  SUBROUTINE S8B(X,Z,Y)
+  SUBROUTINE S8B(X,Z,Y)     ! { dg-error "Ambiguous interfaces" }
     INTEGER,OPTIONAL :: X
     INTEGER :: Z
     REAL :: Y
-  END SUBROUTINE S8B ! { dg-error "Ambiguous interfaces" }
+  END SUBROUTINE S8B
 END INTERFACE BAD8
 real :: a, b
 integer :: i, j
Index: gcc/testsuite/gfortran.dg/interface_7.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_7.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/interface_7.f90	(working copy)
@@ -11,20 +11,20 @@  module xx
     SUBROUTINE S9A(X)
       REAL :: X
     END SUBROUTINE S9A
-    SUBROUTINE S9B(X)
+    SUBROUTINE S9B(X)     ! { dg-error "Ambiguous interfaces" }
       INTERFACE
         FUNCTION X(A)
           REAL :: X,A
         END FUNCTION X
       END INTERFACE
     END SUBROUTINE S9B
-    SUBROUTINE S9C(X)
+    SUBROUTINE S9C(X)     ! { dg-error "Ambiguous interfaces" }
       INTERFACE
         FUNCTION X(A)
           REAL :: X
           INTEGER :: A
         END FUNCTION X
       END INTERFACE
-    END SUBROUTINE S9C  ! { dg-error "Ambiguous interfaces" }
+    END SUBROUTINE S9C
   END INTERFACE BAD9
 end module xx
Index: gcc/testsuite/gfortran.dg/no_arg_check_3.f90
===================================================================
--- gcc/testsuite/gfortran.dg/no_arg_check_3.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/no_arg_check_3.f90	(working copy)
@@ -55,23 +55,23 @@  subroutine nine()
     end subroutine okay
   end interface
   interface two
-    subroutine ambig1(x)
+    subroutine ambig1(x)  ! { dg-error "Ambiguous interfaces" }
 !GCC$ attributes NO_ARG_CHECK :: x
       integer :: x
     end subroutine ambig1
-    subroutine ambig2(x)
+    subroutine ambig2(x)  ! { dg-error "Ambiguous interfaces" }
 !GCC$ attributes NO_ARG_CHECK :: x
       integer :: x(*)
-    end subroutine ambig2 ! { dg-error "Ambiguous interfaces 'ambig2' and 'ambig1' in generic interface 'two'" }
+    end subroutine ambig2
   end interface
   interface three
-    subroutine ambig3(x)
+    subroutine ambig3(x)   ! { dg-error "Ambiguous interfaces" }
 !GCC$ attributes NO_ARG_CHECK :: x
       integer :: x
     end subroutine ambig3
-    subroutine ambig4(x)
+    subroutine ambig4(x)   ! { dg-error "Ambiguous interfaces" }
       integer :: x
-    end subroutine ambig4 ! { dg-error "Ambiguous interfaces 'ambig4' and 'ambig3' in generic interface 'three'" }
+    end subroutine ambig4
   end interface
 end subroutine nine
 
Index: gcc/testsuite/gfortran.dg/operator_5.f90
===================================================================
--- gcc/testsuite/gfortran.dg/operator_5.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/operator_5.f90	(working copy)
@@ -16,7 +16,7 @@  MODULE mod_t
   END INTERFACE
 
   INTERFACE OPERATOR(.FOO.)
-    MODULE PROCEDURE t_bar                  ! { dg-error "Ambiguous interfaces" }
+    MODULE PROCEDURE t_bar
   END INTERFACE
 
   ! intrinsic operator
@@ -29,7 +29,7 @@  MODULE mod_t
   END INTERFACE
 
   INTERFACE OPERATOR(==)
-    MODULE PROCEDURE t_bar                  ! { dg-error "Ambiguous interfaces" }
+    MODULE PROCEDURE t_bar
   END INTERFACE
 
   INTERFACE OPERATOR(.eq.)
@@ -37,12 +37,12 @@  MODULE mod_t
   END INTERFACE
 
 CONTAINS
-  LOGICAL FUNCTION t_foo(this, other)
+  LOGICAL FUNCTION t_foo(this, other)  ! { dg-error "Ambiguous interfaces" }
     TYPE(t), INTENT(in) :: this, other
     t_foo = .FALSE.
   END FUNCTION
 
-  LOGICAL FUNCTION t_bar(this, other)
+  LOGICAL FUNCTION t_bar(this, other)  ! { dg-error "Ambiguous interfaces" }
     TYPE(t), INTENT(in) :: this, other
     t_bar = .FALSE.
   END FUNCTION
Index: gcc/testsuite/gfortran.dg/pr77406.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr77406.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr77406.f90	(working copy)
@@ -0,0 +1,34 @@ 
+! { dg-do compile }
+! { dg-options "-w" }
+module m
+   interface s
+      subroutine s1(*)  ! { dg-error "Ambiguous interfaces" }
+      end
+      subroutine s2(*)  ! { dg-error "Ambiguous interfaces" }
+      end
+   end interface 
+   interface t
+      subroutine t1(*)
+      end
+      subroutine t2(*,*)
+      end
+   end interface
+   interface u
+      subroutine u1(*,x)
+      end
+      subroutine u2(*,i)
+      end
+   end interface
+   interface v
+      subroutine v1(*,*)  ! { dg-error "Ambiguous interfaces" }
+      end
+      subroutine v2(*,*)  ! { dg-error "Ambiguous interfaces" }
+      end
+   end interface
+   interface w
+      subroutine w1(*,i)  ! { dg-error "Ambiguous interfaces" }
+      end
+      subroutine w2(*,j)  ! { dg-error "Ambiguous interfaces" }
+      end
+   end interface
+end
Index: gcc/testsuite/gfortran.dg/proc_ptr_comp_20.f90
===================================================================
--- gcc/testsuite/gfortran.dg/proc_ptr_comp_20.f90	(revision 239847)
+++ gcc/testsuite/gfortran.dg/proc_ptr_comp_20.f90	(working copy)
@@ -7,11 +7,11 @@ 
 implicit none
 
 interface func
-  procedure f1,f2 ! { dg-error "Ambiguous interfaces" }
+  procedure f1,f2
 end interface
 
 interface operator(.op.)
-  procedure f1,f2 ! { dg-error "Ambiguous interfaces" }
+  procedure f1,f2
 end interface
 
 type :: t1
@@ -35,12 +35,12 @@  o1%ppc => o2%ppc  ! { dg-error "Type mis
 
 contains
 
-  real function f1(a,b)
+  real function f1(a,b)    ! { dg-error "Ambiguous interfaces" }
     real,intent(in) :: a,b
     f1 = a + b
   end function
 
-  integer function f2(a,b)
+  integer function f2(a,b) ! { dg-error "Ambiguous interfaces" }
     real,intent(in) :: a,b
     f2 = a - b
   end function