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]>

Reply via email to