https://gcc.gnu.org/g:b3f51ea894947e495baffc67407647a3b25acdd5
commit r15-7150-gb3f51ea894947e495baffc67407647a3b25acdd5 Author: Paul Thomas <pa...@gcc.gnu.org> Date: Thu Jan 23 08:27:04 2025 +0000 Fortran: Regression- fix ICE at fortran/trans-decl.c:1575 [PR96087] 2025-01-23 Paul Thomas <pa...@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. Diff: --- gcc/fortran/trans-decl.cc | 15 ++++++++++++ gcc/fortran/trans-expr.cc | 2 +- gcc/testsuite/gfortran.dg/pr96087.f90 | 46 +++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 4ae22a5584d0..97bb0a418581 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -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); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index dcf42d531756..78caf1f8996c 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -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 index 000000000000..6c75d4f0cf27 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr96087.f90 @@ -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