https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107742
Christopher Albert <albert at tugraz dot at> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |albert at tugraz dot at
--- Comment #1 from Christopher Albert <albert at tugraz dot at> ---
Created attachment 62729
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=62729&action=edit
[PATCH] fortran: Fix ICE and self-assignment bugs with recursive allocatable
finalizers
This popped up in follow-up tests after fixing
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121628 . Compared to that one, it
is a much smaller change. Should I post it on the mailing list too, or do you
prefer to handle it via the bug tracker directly?
---
>From bf33ca3ab5b4ba19f92c5cc6be8f345f5d7277c7 Mon Sep 17 00:00:00 2001
From: Christopher Albert <[email protected]>
Date: Fri, 7 Nov 2025 12:41:42 +0100
Subject: [PATCH] fortran: Fix ICE and self-assignment bugs with recursive
allocatable finalizers [PR90519]
Derived types with recursive allocatable components and FINAL procedures
trigger an ICE in gimplify_call_expr because the finalizer wrapper's result
symbol references itself (final->result = final), creating a cycle. This
patch creates a separate __result_<typename> symbol to break the cycle.
Self-assignment (a = a) with such types causes use-after-free because the
left-hand side is finalized before copying, destroying the source. The patch
adds detection using gfc_dep_compare_expr at compile time and pointer
comparison at runtime to skip finalization when lhs == rhs.
Test pr112459.f90 now expects 6 _final calls instead of 12 because separate
result symbols eliminate double-counting in tree dumps.
gcc/fortran/ChangeLog:
PR fortran/90519
* class.cc (generate_finalization_wrapper): Create separate result
symbol for finalizer wrapper functions instead of self-referencing
the procedure symbol, avoiding ICE in gimplify_call_expr.
* trans-expr.cc (gfc_trans_scalar_assign): Skip finalization for
self-assignment when deep_copy is enabled, using compile-time
dependency analysis and runtime pointer comparison to detect
identity between lvalue and rvalue.
(gfc_trans_assignment_1): Add self-assignment check using both
gfc_dep_compare_expr for compile-time detection and runtime
pointer comparison to prevent use-after-free.
gcc/testsuite/ChangeLog:
PR fortran/90519
* gfortran.dg/finalizer_recursive_alloc_1.f90: New test for ICE fix.
* gfortran.dg/finalizer_recursive_alloc_2.f90: New execution test.
* gfortran.dg/finalizer_self_assign.f90: New test for self-assignment.
* gfortran.dg/pr112459.f90: Update to expect 6 _final calls instead
of 12, reflecting corrected self-assignment behavior.
Signed-off-by: Christopher Albert <[email protected]>