https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110626

--- Comment #16 from Javier Martín <habbit89 at hotmail dot es> ---
Hi everyone, thanks for looking into this issue. I am surprised that the double
finalization is "intended", and indeed back when I originally raised this I had
no access to ifx or new-flang to check that they also implement the standard in
such a way. However, reference-counting schemes can deal with multiple
finalization just fine.

The issue with gfortran is that the final procedure sees *the same value*
twice, which breaks RC. This does _not_ happen in the other implementations,
see the output from Tomáš's example in comment #13 where gfortran shows
"finalize 42" twice while the others show "finalize 42" followed by "finalize
-1". Perhaps the issue is that this weird temporary is being created separate
from the actual value to be finalized, is _copied_ from it _without_ calling
the assignment operator (as if it was trivial), but then it is finalized _with_
the user-provided code. In the other implementations, it is _the actual object_
being finalized twice, not a separate temporary. You can see this by running 
my original testcase, showing not just values but also memory locations, with
flang.

$ flang testbug.f90 ; ./a.out 
 objects of type A in subroutine
o1:     7FFD3FC6FF90
o2:     7FFD3FC6FF98
dtor: -1     7FFD3FC6FF98
copy: 15 from     7FFD3FC6FF88 to     7FFD3FC6FF98
dtor: 16     7FFD3FC6FF98
copy: 15 from     7FFD3FC6FF80 to     7FFD3FC6FF98
dtor: 16     7FFD3FC6FF98
dtor: 15     7FFD3FC6FF90
 objects of type B in subroutine
o1:     7FFD3FC6FF90
o2:     7FFD3FC6FF98
dtor: -1     7FFD3FC6FF98
dtor: -2     7FFD3FC6FF98
copy: 15 from     7FFD3FC6FF90 to     7FFD3FC6FF98
dtor: 16     7FFD3FC6FF98
dtor: -2     7FFD3FC6FF98
copy: 15 from     7FFD3FC6FF90 to     7FFD3FC6FF98
dtor: 16     7FFD3FC6FF98
dtor: 15     7FFD3FC6FF90

The finalizer for o2 is called twice for the composite object, yes, but the
second time around the code sees an already-finalized object (-2 in my example)
and so it could have code in place to avoid the double-free.

Thus, in gfortran, either the temporary itself should not be created (like
flang), or operations for it should not be considered trivial, resulting in
_another_ call to the assignment operator and a correct call to the final
subroutine.

Reply via email to