On 11/6/26 9:47 AM, Harald Anlauf wrote:
Hi Jerry,

just tried your patch and it seems to work mostly.

There's a cornercase I found.  In subroutine work, try:

     call s ((ta))   ! OK
     call s (((ta))) ! OK
     call s ([(ta)]) ! OK
     call s ([ta])   ! OK
     call s (([ta])) ! heap-use-after-free with -fsanitize=address

The latter case needs to be tracked for further investigation.
It is also confirmed by valgrind (several invalid reads).

Thanks,
Harald

Hi Harald,

Thanks for testing.  I will open a separate
PR for it and look at it after this one.

See further below.


Am 06.11.26 um 11:10 AM schrieb Mikael Morin:
Le 06/11/2026 à 01:14, Jerry DeLisle a écrit :
See attached patch. For a parenthesized array of a type with
allocatable components, gfc_conv_expr_descriptor builds the temporary
by element assignment, so it shares the components of the variable.
After the call, gfc_conv_procedure_call deep copies that temporary into
new storage only so that it can free the copied components, and the
new storage is never freed.  For a CLASS array the elements are copied
with the vtable's _copy, which is deep, and nothing frees their
components.  The patch drops the copy and the free for a TYPE
temporary, which leaves the components with the variable, and calls
the vtable's finalization wrapper on a CLASS temporary, which frees the
components of each element.

Following the discussion in the PR, the copy of a parenthesized scalar
CLASS actual argument is now PR128478, and the test makes its calls
from a subroutine, so the temporaries are lost when it returns, not at
program end.

Start with gfc_conv_procedure_call in trans-expr.cc: the new condition
keeps a parenthesized TYPE variable out of the copy-and-free block, and
parenthesized_variable only names the test that was already there.
Then the gfc_conv_expr_descriptor hunk in trans-array.cc, which
finalizes the CLASS temporary.  The rest is the new test.

Regression tested on x86_64.

OK for mainline?


I'm not sure about the use of the sanitizer for the test.  Does it catch the memory leak?
Otherwise looks good.

The original test case found leaked. The segfault could be a random occurence so I wanted to be certail by putting the test case in asan.

Thanks

Jerry>>
Regards,

Jerry

---

fortran: [PR128357] Memory leaks with parenthesized alloc-comp variables

A parenthesized array of a type with allocatable components leaked on
each use as an actual argument or ASSOCIATE selector.  A TYPE temporary
shares the components of the variable, yet after the call it was deep
copied into new storage so that its components could be freed, and that
storage was never freed.  A CLASS temporary is a deep copy made through
the vtable, and the components of its elements were never freed.  Pass
a TYPE temporary without copying or freeing its components, and
finalize a CLASS temporary through the vtable after its use.

Assisted-by: Claude Opus 5.5

    PR fortran/128357

gcc/fortran/ChangeLog:

    * trans-array.cc (gfc_conv_expr_descriptor): Finalize the temporary
    for a CLASS operator expression through the vtable.
    * trans-expr.cc (parenthesized_variable): New function.
    (gfc_conv_procedure_call): Use it.  Do not copy or free the
    allocatable components of the temporary for a parenthesized TYPE
    variable.

gcc/testsuite/ChangeLog:

    * gfortran.dg/asan/paren_alloc_comp_leak_1.f90: New test.



Reply via email to