[gcc r16-8320] Fortran: Fix use-after-free in gfc_fixup_sibling_symbols [PR95879]
Paul Thomas
pault@gcc.gnu.org
Sat Mar 28 09:09:05 GMT 2026
https://gcc.gnu.org/g:ee931e5b7eab59916f4dd77a4ad20c1202153036
commit r16-8320-gee931e5b7eab59916f4dd77a4ad20c1202153036
Author: Paul Thomas <pault@gcc.gnu.org>
Date: Sat Mar 28 09:08:54 2026 +0000
Fortran: Fix use-after-free in gfc_fixup_sibling_symbols [PR95879]
2026-03-28 Paul Thomas <pault@gcc.gnu.org>
gcc/fortran
PR fortran/95879
* parse.cc (fixup_st_func_formals): New function to update
statement function formal argument lists referencing a symbol
about to be freed.
(gfc_fixup_sibling_symbols): Call fixup_st_func_formals before
gfc_release_symbol.
gcc/testsuite
PR fortran/95879
* gfortran.dg/pr95879.f90: New test.
Diff:
---
gcc/fortran/parse.cc | 27 +++++++++++++++++++++++++++
gcc/testsuite/gfortran.dg/pr95879.f90 | 30 ++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index e397ea6015cd..a41bf090c339 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -6853,6 +6853,28 @@ parse_executable (gfc_statement st)
}
+/* Update statement function formal argument lists that reference OLD_SYM
+ to point to NEW_SYM instead. This prevents use-after-free when
+ gfc_fixup_sibling_symbols replaces and frees a symbol that is also
+ used as a statement function dummy argument (PR95879). */
+
+static void
+fixup_st_func_formals (gfc_symtree *st, gfc_symbol *old_sym,
+ gfc_symbol *new_sym)
+{
+ if (st == NULL)
+ return;
+
+ fixup_st_func_formals (st->left, old_sym, new_sym);
+ fixup_st_func_formals (st->right, old_sym, new_sym);
+
+ if (st->n.sym && st->n.sym->attr.proc == PROC_ST_FUNCTION)
+ for (gfc_formal_arglist *fa = st->n.sym->formal; fa; fa = fa->next)
+ if (fa->sym == old_sym)
+ fa->sym = new_sym;
+}
+
+
/* Fix the symbols for sibling functions. These are incorrectly added to
the child namespace as the parser didn't know about this procedure. */
@@ -6907,6 +6929,11 @@ gfc_fixup_sibling_symbols (gfc_symbol *sym, gfc_namespace *siblings)
sym->refs++;
if (imported)
sym->attr.imported = 1;
+
+ /* Update statement function formal argument lists that still
+ reference old_sym before releasing it (PR95879). */
+ fixup_st_func_formals (ns->sym_root, old_sym, sym);
+
gfc_release_symbol (old_sym);
}
diff --git a/gcc/testsuite/gfortran.dg/pr95879.f90 b/gcc/testsuite/gfortran.dg/pr95879.f90
new file mode 100644
index 000000000000..67c8af0de3bc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr95879.f90
@@ -0,0 +1,30 @@
+! { dg-do compile }
+! { dg-options "-std=f2018" }
+! PR fortran/95879
+! Contributed by G. Steinmetz <gscfq@t-online.de>
+!
+! Use-after-free in gfc_resolve_formal_arglist when a contained subroutine
+! has a statement function whose dummy argument name matches a symbol
+! replaced by gfc_fixup_sibling_symbols.
+
+module m1
+contains
+ integer function f(x) bind(c)
+ use iso_c_binding
+ contains
+ subroutine s
+ c_funloc(f) = x ! { dg-warning "Obsolescent feature: Statement function" }
+ end
+ end
+end
+
+module m2
+contains
+ integer function f(x)
+ use iso_c_binding
+ contains
+ subroutine s
+ c_funloc(f) = x ! { dg-warning "Obsolescent feature: Statement function" }
+ end
+ end
+end
More information about the Gcc-cvs
mailing list