Re: [Fortran, Patch, PR119349, v1] Fix regression of polymorphic dummy sourced from array constructors.

2025-03-20 Thread Jerry D

On 3/20/25 9:20 AM, Andre Vehreschild wrote:

Hi all,

attached patch fixes a 15-regression where an element of an actual
temporary array, i.e., elemental([ e1, e2...]) passed to the formal polymorphic
dummy leads to a double free of the derived types components. This patch
prevents this by preventing the deallocation of the array constructors
temporary, when the formal is polymorphic. ...

Folks its so hard to explain this in prose. I rewrote above paragraph the third
time now. And I still don't understand on re-reading. So here is some pseudo
code:

struct derived {
   char *c; // This is the component suffering from double-free
};

derived[2] atmp = [ derived(""), derived("")]

forall a in atmp
   derived t_a = a; // <- Copy of a, but no deep copy, i.e. t_a.c == a.c
   class_temp = class_derived(a); // set _vtype left out for brevity
   call elemental_function(class_temp);
   if (class_temp._data.c != NULL)
 free(class_temp._data.c); // and set it to NULL
   if (t_a.c != NULL)
 free(t_a.c); // BOOM, this is freeing the same c
end

Generating the last if-block and the free is what this patch prevents for
polymorphic dummys that stem from an array construction. And only for those.

Sorry, I am having a hard time explaining things today. So I hope the code
above will do.

Regtested ok on x86_64-pc-linux-gnu / F41. Ok for mainline?


OK and thanks for the fix. Your prose is fine and your comment in the 
code suffices.


Thanks for the patch.

Jerry


Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de




[GSoC] Fortran – run-time argument checking

2025-03-20 Thread Gwen Fu
I'm very sorry that I've only just gotten in touch with the Gfortran
community! I've been trying to fix a bug in the GCC community for some time
(although I'm still working on it) and trying to understand the internal
components of GCC and its operation process.
I'm very sorry that I just got in touch with the Gfortran community now! I
have been trying to fix a bug in the GCC community for some time (although
I'm still working on it), and trying to understand the internal components
of GCC and the running process.
I have some superficial doubts about this project:
1. Which version of fortran does the "older Fortran code" refer to?
2. "A pointer to the called function is stored alongside to permit calls
from uninstrumented code to instrumented code." Why do we need to call the
detected function? Is the purpose of our project just to check whether the
function parameters match the passed parameters?
3. Is Fortran a strongly typed language like C++?


[Fortran, Patch, PR119349, v1] Fix regression of polymorphic dummy sourced from array constructors.

2025-03-20 Thread Andre Vehreschild
Hi all,

attached patch fixes a 15-regression where an element of an actual
temporary array, i.e., elemental([ e1, e2...]) passed to the formal polymorphic
dummy leads to a double free of the derived types components. This patch
prevents this by preventing the deallocation of the array constructors
temporary, when the formal is polymorphic. ...

Folks its so hard to explain this in prose. I rewrote above paragraph the third
time now. And I still don't understand on re-reading. So here is some pseudo
code:

struct derived {
  char *c; // This is the component suffering from double-free
};

derived[2] atmp = [ derived(""), derived("")]

forall a in atmp
  derived t_a = a; // <- Copy of a, but no deep copy, i.e. t_a.c == a.c
  class_temp = class_derived(a); // set _vtype left out for brevity
  call elemental_function(class_temp);
  if (class_temp._data.c != NULL)
free(class_temp._data.c); // and set it to NULL
  if (t_a.c != NULL)
free(t_a.c); // BOOM, this is freeing the same c
end

Generating the last if-block and the free is what this patch prevents for
polymorphic dummys that stem from an array construction. And only for those.

Sorry, I am having a hard time explaining things today. So I hope the code
above will do.

Regtested ok on x86_64-pc-linux-gnu / F41. Ok for mainline?

Regards,
Andre
--
Andre Vehreschild * Email: vehre ad gmx dot de
From 8f9c24fe01a1e34bea2e1c95102329562abdb9e1 Mon Sep 17 00:00:00 2001
From: Andre Vehreschild 
Date: Thu, 20 Mar 2025 13:37:21 +0100
Subject: [PATCH] Fortran: Fix double free on polymorphic array dummy argument
 [PR119349]

Calling elemental routines with polymorphic formals leads to generation
of a temporary polymorphic variable and code for its deallocation.
Sourcing this element from an array constructor the latter now is
prevented from generating a second deallocation.

	PR fortran/119349

gcc/fortran/ChangeLog:

	* trans-expr.cc (gfc_conv_procedure_call): Prevent deallocation
	of array temporary for polymorphic temporary argument.

gcc/testsuite/ChangeLog:

	* gfortran.dg/class_79.f90: New test.
---
 gcc/fortran/trans-expr.cc  |  6 +-
 gcc/testsuite/gfortran.dg/class_79.f90 | 25 +
 2 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/class_79.f90

diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index d965539f11e..923d46cb47c 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -7994,7 +7994,11 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 	  gfc_add_expr_to_block (&se->post, local_tmp);
 	}

-	  if (!finalized && !e->must_finalize)
+	  /* Items of array expressions passed to a polymorphic formal arguments
+	 create their own clean up, so prevent double free.  */
+	  if (!finalized && !e->must_finalize
+	  && !(e->expr_type == EXPR_ARRAY && fsym
+		   && fsym->ts.type == BT_CLASS))
 	{
 	  bool scalar_res_outside_loop;
 	  scalar_res_outside_loop = e->expr_type == EXPR_FUNCTION
diff --git a/gcc/testsuite/gfortran.dg/class_79.f90 b/gcc/testsuite/gfortran.dg/class_79.f90
new file mode 100644
index 000..a2226e47aff
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_79.f90
@@ -0,0 +1,25 @@
+!{ dg-do run }
+
+! Check double free on array constructor in argument list is fixed.
+! Contributed by Damian Rouson  
+program pr119349
+  implicit none
+
+  type string_t
+character(len=:), allocatable :: string_
+  end type
+
+  print *, true([string()])
+
+contains
+
+  type(string_t) function string()
+string%string_ = ""
+  end function
+
+  logical elemental function true(rhs)
+class(string_t), intent(in) :: rhs
+true = .true.
+  end function
+
+end program
--
2.48.1