aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJanus Weil <janus@gcc.gnu.org>2013-08-09 18:57:58 +0200
committerJanus Weil <janus@gcc.gnu.org>2013-08-09 18:57:58 +0200
commit36849c21ccee087a778360d3a5dce38d1f7dd586 (patch)
treefd9df8c7c1a53d0c5c154816dc1d87d217fbbf33 /gcc
parent042ae7d242e9def81372edef1eff1046851699f0 (diff)
downloadgcc-36849c21ccee087a778360d3a5dce38d1f7dd586.zip
gcc-36849c21ccee087a778360d3a5dce38d1f7dd586.tar.gz
gcc-36849c21ccee087a778360d3a5dce38d1f7dd586.tar.bz2
re PR fortran/58058 (Memory leak with transfer function)
2013-08-09 Janus Weil <janus@gcc.gnu.org> PR fortran/58058 * trans-intrinsic.c (gfc_conv_intrinsic_transfer): Free the temporary string, if necessary. 2013-08-09 Janus Weil <janus@gcc.gnu.org> PR fortran/58058 * gfortran.dg/transfer_intrinsic_6.f90: New. From-SVN: r201633
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/trans-intrinsic.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f9020
4 files changed, 39 insertions, 2 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index bcd91a9..8aa70a3 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2013-08-09 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58058
+ * trans-intrinsic.c (gfc_conv_intrinsic_transfer): Free the temporary
+ string, if necessary.
+
2013-08-06 Martin Jambor <mjambor@suse.cz>
PR fortran/57987
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 3fbf193..6b85b5b 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 9f9a932..f149784 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-08-09 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58058
+ * gfortran.dg/transfer_intrinsic_6.f90: New.
+
2013-08-09 Paolo Carlini <paolo.carlini@oracle.com>
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 0000000..e76bc49
--- /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 <thomas.jourdan@orange.fr>
+
+ 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" } }