Hello world,

this was an interesting regression.  It came from my recent
patch, where an assert was triggered because a procedure artificial
dummy argument generated for a global symbol did not have the
information if if was a function or a subroutine.  Fixed by
adding the information in gfc_get_formal_from_actual_arglist.
This information then uncovered some new errors, also in the
testsuite, which needed fixing.  Finally, the error is made to
look a bit nicer, so the user gets a pointer to where the
original interface comes from, like this:

10 | CALL bar (test2) ! { dg-error "Interface mismatch in dummy procedure" }
      |              1
......
16 | CALL bar (test) ! { dg-error "Interface mismatch in dummy procedure" }
      |              2
Fehler: Interface mismatch in dummy procedure at (1) conflichts with (2): 'test2' is not a subroutine
Regression-tested. OK for trunk?

Best regards

        Thomas

gcc/fortran/ChangeLog:

        PR fortran/118845
        * interface.cc (compare_parameter): If the formal attribute has been
        generated from an actual argument list, also output an pointer to
        there in case of an error.
        (gfc_get_formal_from_actual_arglist): Set function and subroutine
        attributes and (if it is a function) the typespec from the actual
        argument.

gcc/testsuite/ChangeLog:

        PR fortran/118845
        * gfortran.dg/recursive_check_4.f03: Adjust call so types matche.
        * gfortran.dg/recursive_check_6.f03: Likewise.
        * gfortran.dg/specifics_2.f90: Adjust calls so types match.
        * gfortran.dg/interface_52.f90: New test.
        * gfortran.dg/interface_53.f90: New test.
diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index fdde84db80d..edec907d33a 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -2474,8 +2474,16 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
 					   sizeof(err),NULL, NULL))
 	{
 	  if (where)
-	    gfc_error_opt (0, "Interface mismatch in dummy procedure %qs at %L:"
-			   " %s", formal->name, &actual->where, err);
+	    {
+	      /* Artificially generated symbol names would only confuse.  */
+	      if (formal->attr.artificial)
+		gfc_error_opt (0, "Interface mismatch in dummy procedure "
+			       "at %L conflicts with %L: %s", &actual->where,
+			       &formal->declared_at, err);
+	      else
+		gfc_error_opt (0, "Interface mismatch in dummy procedure %qs "
+			       "at %L: %s", formal->name, &actual->where, err);
+	    }
 	  return false;
 	}
 
@@ -2483,8 +2491,16 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
 				   sizeof(err), NULL, NULL))
 	{
 	  if (where)
-	    gfc_error_opt (0, "Interface mismatch in dummy procedure %qs at %L:"
-			   " %s", formal->name, &actual->where, err);
+	    {
+	      if (formal->attr.artificial)
+		gfc_error_opt (0, "Interface mismatch in dummy procedure "
+			       "at %L conflichts with %L: %s", &actual->where,
+			       &formal->declared_at, err);
+	      else
+		gfc_error_opt (0, "Interface mismatch in dummy procedure %qs at "
+			       "%L: %s", formal->name, &actual->where, err);
+
+	    }
 	  return false;
 	}
 
@@ -5822,7 +5838,14 @@ gfc_get_formal_from_actual_arglist (gfc_symbol *sym,
 	  gfc_get_symbol (name, gfc_current_ns, &s);
 	  if (a->expr->ts.type == BT_PROCEDURE)
 	    {
+	      gfc_symbol *asym = a->expr->symtree->n.sym;
 	      s->attr.flavor = FL_PROCEDURE;
+	      if (asym->attr.function)
+		{
+		  s->attr.function = 1;
+		  s->ts = asym->ts;
+		}
+	      s->attr.subroutine = asym->attr.subroutine;
 	    }
 	  else
 	    {
diff --git a/gcc/testsuite/gfortran.dg/interface_52.f90 b/gcc/testsuite/gfortran.dg/interface_52.f90
new file mode 100644
index 00000000000..4d619241c27
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/interface_52.f90
@@ -0,0 +1,20 @@
+  ! { dg-do compile }
+MODULE m
+  IMPLICIT NONE
+
+CONTAINS
+
+  SUBROUTINE test ()
+    IMPLICIT NONE
+
+    CALL bar (test2) ! { dg-error "Interface mismatch in dummy procedure" }
+  END SUBROUTINE test
+
+  INTEGER FUNCTION test2 () RESULT (x)
+    IMPLICIT NONE
+
+    CALL bar (test) ! { dg-error "Interface mismatch in dummy procedure" }
+  END FUNCTION test2
+
+END MODULE m
+
diff --git a/gcc/testsuite/gfortran.dg/interface_53.f90 b/gcc/testsuite/gfortran.dg/interface_53.f90
new file mode 100644
index 00000000000..99a2b959463
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/interface_53.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+! PR 118845 - reduced from a segfault in Lapack.
+SUBROUTINE SDRVES(  RESULT )
+  external SSLECT
+  CALL SGEES( SSLECT )
+  CALL SGEES( SSLECT )
+  RESULT = SSLECT( 1, 2 )
+END
diff --git a/gcc/testsuite/gfortran.dg/recursive_check_4.f03 b/gcc/testsuite/gfortran.dg/recursive_check_4.f03
index ece42ca2312..da45762f9b1 100644
--- a/gcc/testsuite/gfortran.dg/recursive_check_4.f03
+++ b/gcc/testsuite/gfortran.dg/recursive_check_4.f03
@@ -20,7 +20,7 @@ CONTAINS
     IMPLICIT NONE
     PROCEDURE(test2), POINTER :: procptr
 
-    CALL bar (test2) ! { dg-warning "Non-RECURSIVE" }
+    CALL bar2 (test2) ! { dg-warning "Non-RECURSIVE" }
     procptr => test2 ! { dg-warning "Non-RECURSIVE" }
 
     x = 1812
diff --git a/gcc/testsuite/gfortran.dg/recursive_check_6.f03 b/gcc/testsuite/gfortran.dg/recursive_check_6.f03
index 9414f587b90..732d7bc627d 100644
--- a/gcc/testsuite/gfortran.dg/recursive_check_6.f03
+++ b/gcc/testsuite/gfortran.dg/recursive_check_6.f03
@@ -31,7 +31,7 @@ CONTAINS
 
       bar = test_func () ! { dg-error "not RECURSIVE" }
       procptr => test_func ! { dg-warning "Non-RECURSIVE" }
-      CALL foobar (test_func) ! { dg-warning "Non-RECURSIVE" }
+      CALL foobar2 (test_func) ! { dg-warning "Non-RECURSIVE" }
     END FUNCTION bar
   END FUNCTION test_func
 
diff --git a/gcc/testsuite/gfortran.dg/specifics_2.f90 b/gcc/testsuite/gfortran.dg/specifics_2.f90
index 4de0925647f..923ab9ebfed 100644
--- a/gcc/testsuite/gfortran.dg/specifics_2.f90
+++ b/gcc/testsuite/gfortran.dg/specifics_2.f90
@@ -1,5 +1,6 @@
 ! { dg-do compile }
-! This is the list of intrinsics allowed as actual arguments
+  ! This is the list of intrinsics allowed as actual arguments
+  implicit none
  intrinsic abs,acos,acosh,aimag,aint,alog,alog10,amod,anint,asin,asinh,atan,&
  atan2,atanh,cabs,ccos,cexp,clog,conjg,cos,cosh,csin,csqrt,dabs,dacos,&
  dacosh,dasin,dasinh,datan,datan2,datanh,dconjg,dcos,dcosh,ddim,dexp,dim,&
@@ -7,75 +8,75 @@
  exp,iabs,idim,idnint,index,isign,len,mod,nint,sign,sin,sinh,sqrt,tan,&
  tanh,zabs,zcos,zexp,zlog,zsin,zsqrt
  
-  call foo(abs)
-  call foo(acos)
-  call foo(acosh)
-  call foo(aimag)
-  call foo(aint)
-  call foo(alog)
-  call foo(alog10)
-  call foo(amod)
-  call foo(anint)
-  call foo(asin)
-  call foo(asinh)
-  call foo(atan)
-  call foo(atan2)
-  call foo(atanh)
-  call foo(cabs)
-  call foo(ccos)
-  call foo(cexp)
-  call foo(clog)
-  call foo(conjg)
-  call foo(cos)
-  call foo(cosh)
-  call foo(csin)
-  call foo(csqrt)
-  call foo(dabs)
-  call foo(dacos)
-  call foo(dacosh)
-  call foo(dasin)
-  call foo(dasinh)
-  call foo(datan)
-  call foo(datan2)
-  call foo(datanh)
-  call foo(dconjg)
-  call foo(dcos)
-  call foo(dcosh)
-  call foo(ddim)
-  call foo(dexp)
-  call foo(dim)
-  call foo(dimag)
-  call foo(dint)
-  call foo(dlog)
-  call foo(dlog10)
-  call foo(dmod)
-  call foo(dnint)
-  call foo(dprod)
-  call foo(dsign)
-  call foo(dsin)
-  call foo(dsinh)
-  call foo(dsqrt)
-  call foo(dtan)
-  call foo(dtanh)
-  call foo(exp)
-  call foo(iabs)
-  call foo(idim)
-  call foo(idnint)
-  call foo(index)
-  call foo(isign)
-  call foo(len)
-  call foo(mod)
-  call foo(nint)
-  call foo(sign)
-  call foo(sin)
-  call foo(sinh)
-  call foo(sqrt)
-  call foo(tan)
-  call foo(tanh)
-  call foo(zabs)
-  call foo(zcos)
-  call foo(zexp)
-  call foo(zlog)
-  call foo(zsin)
-  call foo(zsqrt)
+  call foo_r4(abs)
+  call foo_r4(acos)
+  call foo_r4(acosh)
+  call foo_r4(aimag)
+  call foo_r4(aint)
+  call foo_r4(alog)
+  call foo_r4(alog10)
+  call foo_r4(amod)
+  call foo_r4(anint)
+  call foo_r4(asin)
+  call foo_r4(asinh)
+  call foo_r4(atan)
+  call foo_r4(atan2)
+  call foo_r4(atanh)
+  call foo_r4(cabs)
+  call foo_c4(ccos)
+  call foo_c4(cexp)
+  call foo_c4(clog)
+  call foo_c4(conjg)
+  call foo_r4(cos)
+  call foo_r4(cosh)
+  call foo_c4(csin)
+  call foo_c4(csqrt)
+  call foo_r8(dabs)
+  call foo_r8(dacos)
+  call foo_r8(dacosh)
+  call foo_r8(dasin)
+  call foo_r8(dasinh)
+  call foo_r8(datan)
+  call foo_r8(datan2)
+  call foo_r8(datanh)
+  call foo_c8(dconjg)
+  call foo_r8(dcos)
+  call foo_r8(dcosh)
+  call foo_r8(ddim)
+  call foo_r8(dexp)
+  call foo_r8(ddim)
+  call foo_r8(dimag)
+  call foo_r8(dint)
+  call foo_r8(dlog)
+  call foo_r8(dlog10)
+  call foo_r8(dmod)
+  call foo_r8(dnint)
+  call foo_r8(dprod)
+  call foo_r8(dsign)
+  call foo_r8(dsin)
+  call foo_r8(dsinh)
+  call foo_r8(dsqrt)
+  call foo_r8(dtan)
+  call foo_r8(dtanh)
+  call foo_r5(exp)
+  call foo_i4(iabs)
+  call foo_i4(idim)
+  call foo_i4(idnint)
+  call foo_i4(index)
+  call foo_i4(isign)
+  call foo_i4(len)
+  call foo_i4(mod)
+  call foo_i4(nint)
+  call foo_r4(sign)
+  call foo_r4(sin)
+  call foo_r4(sinh)
+  call foo_r4(sqrt)
+  call foo_r4(tan)
+  call foo_r4(tanh)
+  call foo_r8(zabs)
+  call foo_c8(zcos)
+  call foo_c8(zexp)
+  call foo_c8(zlog)
+  call foo_c8(zsin)
+  call foo_c8(zsqrt)
   end

Reply via email to