https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95879

--- Comment #14 from Christopher Albert <albert at tugraz dot at> ---
This bug was never actually fixed on trunk -- the ICE stopped manifesting
because freed memory happened not to be reused, but the underlying
use-after-free is still present on all branches including current trunk.

Building with -fsanitize=address confirms the bug on both the GCC 15
branch point (5d05d496b2b) and current trunk (a0d6c3f23cc):

  ==ERROR: AddressSanitizer: heap-use-after-free
  READ of size 8 in gfc_get_procedure_ns(gfc_symbol*)
    at fortran/symbol.cc:5676
  called from gfc_resolve_formal_arglist at fortran/resolve.cc:287
  freed by gfc_free_symbol at fortran/symbol.cc:3322

Root cause: In the reproducer, `c_funloc(f) = x` inside contained
subroutine `s` is parsed as a statement function definition with `f`
as its dummy argument.  When `parse_contained` runs
`gfc_fixup_sibling_symbols` for the parent function `f`, it finds
the symbol `f` in subroutine `s`'s namespace (the statement function
dummy), replaces it with the parent symbol, and frees the old one.
But the statement function `c_funloc`'s formal argument list still
points to the freed symbol.

Fix: Before releasing old_sym in gfc_fixup_sibling_symbols, walk the
namespace's symtree and update any statement function formal argument
lists that still reference old_sym to point to the replacement symbol.

Patch passes full check-gfortran with zero regressions (75267 PASS,
0 FAIL, 0 XPASS).  Will post to gcc-patches shortly.

PR102818 may be in the same family (ICE in gfc_resolve_formal_arglist
during error recovery) but has a different root cause (bad symbol name
in diagnostic + incomplete error recovery for procedure pointer
conflicting with function name).

Reply via email to