https://gcc.gnu.org/g:cdb4d27a4c2786cf1b1b0eb1872eac6a5f931578

commit r15-7509-gcdb4d27a4c2786cf1b1b0eb1872eac6a5f931578
Author: Thomas Koenig <tkoe...@gcc.gnu.org>
Date:   Thu Feb 13 21:47:39 2025 +0100

    Fix LAPACK build error due to global symbol checking.
    
    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.
    
    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:
---
 gcc/fortran/interface.cc                        |  31 ++++-
 gcc/testsuite/gfortran.dg/interface_52.f90      |  20 ++++
 gcc/testsuite/gfortran.dg/interface_53.f90      |   8 ++
 gcc/testsuite/gfortran.dg/recursive_check_4.f03 |   2 +-
 gcc/testsuite/gfortran.dg/recursive_check_6.f03 |   2 +-
 gcc/testsuite/gfortran.dg/specifics_2.f90       | 145 ++++++++++++------------
 6 files changed, 130 insertions(+), 78 deletions(-)

diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index fdde84db80d0..edec907d33a3 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 000000000000..4d619241c27a
--- /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 000000000000..99a2b9594634
--- /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 ece42ca2312f..da45762f9b1e 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 9414f587b901..732d7bc627d4 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 4de0925647f6..923ab9ebfed8 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