Hi! In the following testcase, sym is the current function, we have created earlier .__result as the PARM_DECL containing pointer to the length to be returned and ..__result is a local VAR_DECL which contains the string length inside of the function and is at the end copied to *.__result.
The reason this ICEs in tree-nested.c is that DECL_CONTEXT of that automatic ..__result variable is NULL, rather than the expected context of the current function. This happens because we attempt to add it to the parent function (which there isn't any), so DECL_CONTEXT is NULL. The following patch fixes that, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-12-05 Jakub Jelinek <ja...@redhat.com> PR fortran/92781 * trans-decl.c (gfc_get_symbol_decl): If sym->backend_decl is current_function_decl, add length to current rather than parent function and expect DECL_CONTEXT (length) to be current_function_decl. * gfortran.dg/pr92781.f90: New test. --- gcc/fortran/trans-decl.c.jj 2019-11-11 21:04:05.000000000 +0100 +++ gcc/fortran/trans-decl.c 2019-12-04 12:32:58.489578829 +0100 @@ -1631,15 +1631,18 @@ gfc_get_symbol_decl (gfc_symbol * sym) /* Add the string length to the same context as the symbol. */ if (DECL_CONTEXT (length) == NULL_TREE) { - if (DECL_CONTEXT (sym->backend_decl) - == current_function_decl) + if (sym->backend_decl == current_function_decl + || (DECL_CONTEXT (sym->backend_decl) + == current_function_decl)) gfc_add_decl_to_function (length); else gfc_add_decl_to_parent_function (length); } - gcc_assert (DECL_CONTEXT (sym->backend_decl) - == DECL_CONTEXT (length)); + gcc_assert (sym->backend_decl == current_function_decl + ? DECL_CONTEXT (length) == current_function_decl + : (DECL_CONTEXT (sym->backend_decl) + == DECL_CONTEXT (length))); gfc_defer_symbol_init (sym); } --- gcc/testsuite/gfortran.dg/pr92781.f90.jj 2019-12-04 12:42:39.063598013 +0100 +++ gcc/testsuite/gfortran.dg/pr92781.f90 2019-12-04 12:42:20.032891766 +0100 @@ -0,0 +1,11 @@ +! PR fortran/92781 +! { dg-do compile } + +function foo () + character(:), allocatable :: foo + call bar () + foo = 'abc' +contains + subroutine bar + end +end Jakub