Hi Andre,

This looks fine to me. You say that this is a regression. How far back does
it go?

OK for mainline and, if required, for backporting.

Thanks for the patch.

Paul


On Fri, 28 Feb 2025 at 15:54, Andre Vehreschild <ve...@gmx.de> wrote:

> Hi all,
>
> on this regression I had to chew a longer time. Assume this Fortran:
>
> type T
>    integer, allocatable:: a
> end type T
>
> result(type T) function bar()
>   allocate(bar%a)
> end function
>
> call foo([bar()])
>
> That Fortran fragment was translated to something like (pseudo code):
>
> T temp;
> T arr[];
> temp = bar();
> arr[0]= temp;
> foo(arr);
> if (temp.a) { free(temp.a); temp.a= NULL;}
> for (i in size(arr))
>   if (arr[i].a) { free(arr[i].a]; <-- double free here
>     arr[i].a = NULL;
> }
>
> I.e., when the derived type result of a function was used in an array
> constructor that was used a function argument, then the temporary used to
> evaluate the function only ones was declared to be of value. When the
> derived
> type now had allocatable components, freeing those would be done on the
> value
> typed temporary (here temp). But later on the array would also be freed.
> Now a
> doulbe free occured, because the temporary variable was already freed. The
> patch fixes this, by preventing the temporary when not necessary, or using
> a
> temporary that is reference into the array, i.e., the memory freed (and
> marked
> as such) is stored at the same location.
>
> So after the patch this looks like this:
>
> T *temp; // Now a pointer!
> T arr[];
> arr[0] = bar();
> temp = &arr[0];
> ... Now we're safe, because freeing temp->a sets arr[0].a to NULL and the
> following loop is safe.
>
> Regtests ok on x86_64-pc-linux-gnu / F41. Ok for mainline?
>
> Regards,
>         Andre
> --
> Andre Vehreschild * Email: vehre ad gmx dot de
>

Reply via email to