aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/fortran/trans-expr.cc6
-rw-r--r--gcc/testsuite/gfortran.dg/class_79.f9025
2 files changed, 30 insertions, 1 deletions
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index d965539..923d46c 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 0000000..a2226e4
--- /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 <damian@archaeologic.codes>
+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