]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fortran: Regression- fix ICE at fortran/trans-decl.c:1575 [PR96087]
authorPaul Thomas <pault@gcc.gnu.org>
Thu, 23 Jan 2025 08:27:04 +0000 (08:27 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Thu, 23 Jan 2025 08:27:17 +0000 (08:27 +0000)
2025-01-23  Paul Thomas  <pault@gcc.gnu.org>

gcc/fortran
PR fortran/96087
* trans-decl.cc (gfc_get_symbol_decl): If a dummy is missing a
backend decl, it is likely that it has come from a module proc
interface. Look for the formal symbol by name in the containing
proc and use its backend decl.
* trans-expr.cc (gfc_apply_interface_mapping_to_expr): For the
same reason, match the name, rather than the symbol address to
perform the mapping.

gcc/testsuite/
PR fortran/96087
* gfortran.dg/pr96087.f90: New test.

gcc/fortran/trans-decl.cc
gcc/fortran/trans-expr.cc
gcc/testsuite/gfortran.dg/pr96087.f90 [new file with mode: 0644]

index 4ae22a5584d0f66d7b7d3246fac864c36c003229..97bb0a4185811efc06919d018f0dc8509d5352b7 100644 (file)
@@ -1722,6 +1722,21 @@ gfc_get_symbol_decl (gfc_symbol * sym)
            sym->backend_decl = DECL_CHAIN (sym->backend_decl);
        }
 
+      /* Automatic array indices in module procedures need the backend_decl
+        to be extracted from the procedure formal arglist.  */
+      if (sym->attr.dummy && !sym->backend_decl)
+       {
+         gfc_formal_arglist *f;
+         for (f = sym->ns->proc_name->formal; f; f = f->next)
+           {
+             gfc_symbol *fsym = f->sym;
+             if (strcmp (sym->name, fsym->name))
+               continue;
+             sym->backend_decl = fsym->backend_decl;
+             break;
+            }
+       }
+
       /* Dummy variables should already have been created.  */
       gcc_assert (sym->backend_decl);
 
index dcf42d53175631a1def5f0b8b5dfc32d5029ecd1..78caf1f8996c94f3d803cde09c8f76194b73fada 100644 (file)
@@ -5099,7 +5099,7 @@ gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
   /* TODO Find out why the condition on expr->symtree had to be moved into
      the loop rather than being outside it, as originally.  */
   for (sym = mapping->syms; sym; sym = sym->next)
-    if (expr->symtree && sym->old == expr->symtree->n.sym)
+    if (expr->symtree && !strcmp (sym->old->name, expr->symtree->n.sym->name))
       {
        if (sym->new_sym->n.sym->backend_decl)
          expr->symtree = sym->new_sym;
diff --git a/gcc/testsuite/gfortran.dg/pr96087.f90 b/gcc/testsuite/gfortran.dg/pr96087.f90
new file mode 100644 (file)
index 0000000..6c75d4f
--- /dev/null
@@ -0,0 +1,46 @@
+! { dg-do run }
+
+module m
+   interface
+      module function f(a, n, b) result(z)
+         integer, intent(in) :: n
+         real :: z(n + 1)
+         real :: a, b
+      end
+   end interface
+contains
+   module procedure f
+      integer :: i
+      do i = 1, size(z)
+        z(i) = real(i)
+      end do
+   end procedure
+end
+
+! Comment 1
+module n
+   interface
+      module subroutine g(n, z)
+         integer, intent(in) :: n
+         real :: z(n)
+      end
+   end interface
+contains
+   module procedure g
+      z = 1
+      if (int (sum (z)) /= n) stop 1
+   end procedure
+end
+
+  use m
+  use n
+  real, allocatable :: r(:)
+  integer :: i = 2
+  r = f (1.0, i+1, 2.0)
+  if (any (r .ne. [(real(i), i = 1,4)])) stop 2
+  if (any (f (3.0, 1, 4.0) .ne. [(real(i), i = 1,2)])) stop 3
+
+  r = [(real (i), i = 10,20)]
+  call g (5, r)
+  if (int (sum (r)) /= (sum ([(i, i = 15,20)]) + 5)) stop 4
+end