[gcc r17-3339] fortran: [PR95542] Fix ICE for deferred-length CHARACTER result via host association
Jerry DeLisle via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:47ec169c00cd1da6a9b0cecf871ccfb2a26fd63c commit r17-3339-g47ec169c00cd1da6a9b0cecf871ccfb2a26fd63c Author: Jerry DeLisle <[email protected]> Date: Sun Jul 12 15:25:18 2026 -0700 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. Diff: --- gcc/fortran/trans-decl.cc | 7 +++++-- gcc/testsuite/gfortran.dg/pr95542.f90 | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index e277f2b2ccc6..5678f69df9ca 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -1846,8 +1846,11 @@ gfc_get_symbol_decl (gfc_symbol * sym) gfc_add_decl_to_parent_function (length); } - gcc_assert (sym->backend_decl == current_function_decl - ? DECL_CONTEXT (length) == current_function_decl + /* 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 (TREE_CODE (sym->backend_decl) == FUNCTION_DECL + ? DECL_CONTEXT (length) == sym->backend_decl : (DECL_CONTEXT (sym->backend_decl) == DECL_CONTEXT (length))); diff --git a/gcc/testsuite/gfortran.dg/pr95542.f90 b/gcc/testsuite/gfortran.dg/pr95542.f90 new file mode 100644 index 000000000000..7bb541e7cba1 --- /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