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

Reply via email to