diff options
-rw-r--r-- | gcc/fortran/trans-expr.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/class_79.f90 | 25 |
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 |