https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90519
--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Harald Anlauf <[email protected]>: https://gcc.gnu.org/g:1eb696fc092ac39cdb55933b20ee25a99d63b907 commit r16-5178-g1eb696fc092ac39cdb55933b20ee25a99d63b907 Author: Christopher Albert <[email protected]> Date: Fri Nov 7 12:41:42 2025 +0100 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. This patch adds detection using gfc_dep_compare_expr at compile time and pointer comparison at runtime to skip finalization when lhs == rhs. Parenthesized self-assignment (a = (a)) creates a temporary, defeating the simple self-assignment detection. This patch adds strip_parentheses() to look through INTRINSIC_PARENTHESES operators and ensure deep_copy is enabled for such cases. Test pr112459.f90 now expects 6 _final calls instead of 12 because separate result symbols eliminate double-counting in tree dumps. PR fortran/90519 gcc/fortran/ChangeLog: * trans-expr.cc (strip_parentheses): New helper function to strip INTRINSIC_PARENTHESES operators from expressions. (is_runtime_conformable): Use strip_parentheses to handle cases like a = (a) when checking for self-assignment. (gfc_trans_assignment_1): Strip parentheses before checking if expr2 is a variable, ensuring deep_copy is enabled for cases like a = (a). Also strip parentheses when checking for self-assignment to avoid use-after-free in finalization. (gfc_trans_scalar_assign): Add comment about parentheses handling. * 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. gcc/testsuite/ChangeLog: * 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 including a = a, a = (a), and a = (((a))) cases using if/stop pattern. * 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]>
