diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index bcd91a92897..8aa70a3adbe 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2013-08-09 Janus Weil + + PR fortran/58058 + * trans-intrinsic.c (gfc_conv_intrinsic_transfer): Free the temporary + string, if necessary. + 2013-08-06 Martin Jambor PR fortran/57987 diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 3fbf193d03c..6b85b5b78db 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -5652,8 +5652,7 @@ scalar_transfer: if (expr->ts.type == BT_CHARACTER) { - tree direct; - tree indirect; + tree direct, indirect, free; ptr = convert (gfc_get_pchar_type (expr->ts.kind), source); tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), @@ -5686,6 +5685,13 @@ scalar_transfer: tmp = build3_v (COND_EXPR, tmp, direct, indirect); gfc_add_expr_to_block (&se->pre, tmp); + /* Free the temporary string, if necessary. */ + free = gfc_call_free (tmpdecl); + tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, + dest_word_len, source_bytes); + tmp = build3_v (COND_EXPR, tmp, free, build_empty_stmt (input_location)); + gfc_add_expr_to_block (&se->post, tmp); + se->expr = tmpdecl; se->string_length = fold_convert (gfc_charlen_type_node, dest_word_len); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9f9a932e15a..f14978402ca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-08-09 Janus Weil + + PR fortran/58058 + * gfortran.dg/transfer_intrinsic_6.f90: New. + 2013-08-09 Paolo Carlini Revert: diff --git a/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90 b/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90 new file mode 100644 index 00000000000..e76bc49aeda --- /dev/null +++ b/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90 @@ -0,0 +1,20 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +! PR 58058: [4.7/4.8/4.9 Regression] Memory leak with transfer function +! +! Contributed by Thomas Jourdan + + implicit none + + integer, dimension(3) :: t1 + character(len=64) :: str + + t1 = (/1,2,3/) + + str = transfer(t1,str) + +end + +! { dg-final { scan-tree-dump-times "__builtin_free" 1 "original" } } +! { dg-final { cleanup-tree-dump "original" } }