[PATCH] fortran PR95542 Fix ICE for deferred-length CHARACTER, result via host association
Jerry D <[email protected]>
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.fortran |
|---|---|
| Message-ID | <[email protected]> |
Attached is the patch I re-discovered while cleaning up worktrees. Regression tested on x86_64. OK for mainline? Regards, Jerry --- fortran: [PR95542] Fix ICE for deferred-length CHARACTER gfc_get_symbol_decl has an assert meant to verify that a deferred-length string's length variable lives in the same scope as the symbol it belongs to. This is wrong when sym->backend_decl is itself the enclosing function's FUNCTION_DECL. The correct comparison is DECL_CONTEXT (length) == sym->backend_decl directly. This was hit when a deferred-length CHARACTER function's own result was assigned to or read from a CONTAINED subprocedure via host association. PR fortran/95542 gcc/fortran/ChangeLog: * trans-decl.cc (gfc_get_symbol_decl): When checking that a deferred-length string's length variable shares the symbol's scope, special-case sym->backend_decl being a FUNCTION_DECL (an implicit function-result variable): compare against sym->backend_decl directly instead of its own DECL_CONTEXT. gcc/testsuite/ChangeLog: * gfortran.dg/pr95542.f90: New test. ---
PR95542.patch
(text/x-patch, 2.8 KB)
From 8516d48a71043b08ba56bcd60f5d23ebce213ff3 Mon Sep 17 00:00:00 2001 From: Jerry DeLisle <[email protected]> Date: Sun, 12 Jul 2026 15:25:18 -0700 Subject: [PATCH] fortran: [PR95542] Fix ICE for deferred-length CHARACTER result via host association gfc_get_symbol_decl has an assert meant to verify that a deferred-length string's length variable lives in the same scope as the symbol it belongs to. This is wrong when sym->backend_decl is itself the enclosing function's FUNCTION_DECL. The correct comparison is DECL_CONTEXT (length) == sym->backend_decl directly. This was hit when a deferred-length CHARACTER function's own result was assigned to or read from a CONTAINED subprocedure via host association. PR fortran/95542 gcc/fortran/ChangeLog: * trans-decl.cc (gfc_get_symbol_decl): When checking that a deferred-length string's length variable shares the symbol's scope, special-case sym->backend_decl being a FUNCTION_DECL (an implicit function-result variable): compare against sym->backend_decl directly instead of its own DECL_CONTEXT. gcc/testsuite/ChangeLog: * gfortran.dg/pr95542.f90: New test. --- gcc/fortran/trans-decl.cc | 9 +++++++-- gcc/testsuite/gfortran.dg/pr95542.f90 | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr95542.f90 diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 47b28c1d003..df5aef2fd86 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -1848,10 +1848,15 @@ gfc_get_symbol_decl (gfc_symbol * sym) gfc_add_decl_to_parent_function (length); } + /* When the symbol's own backend_decl is a FUNCTION_DECL, its + DECL_CONTEXT is where that function itself is declared, not + where its locals live. */ gcc_assert (sym->backend_decl == current_function_decl ? DECL_CONTEXT (length) == current_function_decl - : (DECL_CONTEXT (sym->backend_decl) - == DECL_CONTEXT (length))); + : (TREE_CODE (sym->backend_decl) == FUNCTION_DECL + ? DECL_CONTEXT (length) == sym->backend_decl + : (DECL_CONTEXT (sym->backend_decl) + == DECL_CONTEXT (length)))); gfc_defer_symbol_init (sym); } diff --git a/gcc/testsuite/gfortran.dg/pr95542.f90 b/gcc/testsuite/gfortran.dg/pr95542.f90 new file mode 100644 index 00000000000..7bb541e7cba --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr95542.f90 @@ -0,0 +1,21 @@ +! { dg-do run } +! PR95542 - ICE in gfc_get_symbol_decl, at fortran/trans-decl.cc:1851 +! +function f() + character(:), allocatable :: f + f = 'xyz' + call s +contains + subroutine s + if (f /= 'xyz') stop 1 + end subroutine s +end function f + +program pr95542 + interface + function f() + character(:), allocatable :: f + end function f + end interface + if (f() /= 'xyz') stop 2 +end program pr95542 -- 2.55.0