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 >