Commit 26e46e4b by Paul Thomas

re PR fortran/66079 (memory leak with source allocation in internal subprogram)

2015-06-11  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/66079
	* trans-expr.c (gfc_conv_procedure_call): Allocatable scalar
	function results must be freed and nullified after use. Create
	a temporary to hold the result to prevent duplicate calls.
	* trans-stmt.c (gfc_trans_allocate): Rename temporary variable
	as 'source'. Deallocate allocatable components of non-variable
	'source's.

2015-06-11  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/66079
	* gfortran.dg/allocatable_scalar_13.f90: New test

From-SVN: r224383
parent 133bc698
2015-06-11 Paul Thomas <pault@gcc.gnu.org>
PR fortran/66079
* trans-expr.c (gfc_conv_procedure_call): Allocatable scalar
function results must be freed and nullified after use. Create
a temporary to hold the result to prevent duplicate calls.
* trans-stmt.c (gfc_trans_allocate): Rename temporary variable
as 'source'. Deallocate allocatable components of non-variable
'source's.
2015-06-11 Pierre-Marie de Rodat <derodat@adacore.com>
* f95-lang.c (gfc_create_decls): Register the main translation unit
......@@ -258,7 +268,7 @@
PR fortran/66044
* decl.c(gfc_match_entry): Change a gfc_internal_error() into
a gfc_error()
a gfc_error()
2015-05-18 Steven G. Kargl <kargl@gcc.gnu.org>
......
......@@ -5871,6 +5871,20 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
fntype = TREE_TYPE (TREE_TYPE (se->expr));
se->expr = build_call_vec (TREE_TYPE (fntype), se->expr, arglist);
/* Allocatable scalar function results must be freed and nullified
after use. This necessitates the creation of a temporary to
hold the result to prevent duplicate calls. */
if (!byref && sym->ts.type != BT_CHARACTER
&& sym->attr.allocatable && !sym->attr.dimension)
{
tmp = gfc_create_var (TREE_TYPE (se->expr), NULL);
gfc_add_modify (&se->pre, tmp, se->expr);
se->expr = tmp;
tmp = gfc_call_free (tmp);
gfc_add_expr_to_block (&post, tmp);
gfc_add_modify (&post, se->expr, build_int_cst (TREE_TYPE (se->expr), 0));
}
/* If we have a pointer function, but we don't want a pointer, e.g.
something like
x = f()
......
......@@ -5207,6 +5207,7 @@ gfc_trans_allocate (gfc_code * code)
false, false);
gfc_add_block_to_block (&block, &se.pre);
gfc_add_block_to_block (&post, &se.post);
/* Prevent aliasing, i.e., se.expr may be already a
variable declaration. */
if (!VAR_P (se.expr))
......@@ -5216,8 +5217,20 @@ gfc_trans_allocate (gfc_code * code)
se.expr);
/* We need a regular (non-UID) symbol here, therefore give a
prefix. */
var = gfc_create_var (TREE_TYPE (tmp), "atmp");
var = gfc_create_var (TREE_TYPE (tmp), "source");
gfc_add_modify_loc (input_location, &block, var, tmp);
/* Deallocate any allocatable components after all the allocations
and assignments of expr3 have been completed. */
if (code->expr3->ts.type == BT_DERIVED
&& code->expr3->rank == 0
&& code->expr3->ts.u.derived->attr.alloc_comp)
{
tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
var, 0);
gfc_add_expr_to_block (&post, tmp);
}
tmp = var;
}
else
......
2015-06-11 Paul Thomas <pault@gcc.gnu.org>
PR fortran/66079
* gfortran.dg/allocatable_scalar_13.f90: New test
2015-06-11 Marek Polacek <polacek@redhat.com>
* gcc.dg/fold-xor-3.c: New test.
......@@ -666,7 +671,7 @@
2015-05-27 Honggyu Kim <hong.gyu.kim@lge.com>
PR target/65358
* gcc.dg/pr65358.c: New test.
* gcc.dg/pr65358.c: New test.
2015-05-27 Andre Vehreschild <vehre@gmx.de>
......
! { dg-do run }
! { dg-options "-fdump-tree-original" }
!
! Test the fix for PR66079. The original problem was with the first
! allocate statement. The rest of this testcase fixes problems found
! whilst working on it!
!
! Reported by Damian Rouson <damian@sourceryinstitute.org>
!
type subdata
integer, allocatable :: b
endtype
! block
call newRealVec
! end block
contains
subroutine newRealVec
type(subdata), allocatable :: d, e, f
character(:), allocatable :: g, h, i
character(8), allocatable :: j
allocate(d,source=subdata(1)) ! memory was lost, now OK
allocate(e,source=d) ! OK
allocate(f,source=create (99)) ! memory was lost, now OK
if (d%b .ne. 1) call abort
if (e%b .ne. 1) call abort
if (f%b .ne. 99) call abort
allocate (g, source = greeting1("good day"))
if (g .ne. "good day") call abort
allocate (h, source = greeting2("hello"))
if (h .ne. "hello") call abort
allocate (i, source = greeting3("hiya!"))
if (i .ne. "hiya!") call abort
call greeting4 (j, "Goodbye ") ! Test that dummy arguments are OK
if (j .ne. "Goodbye ") call abort
end subroutine
function create (arg) result(res)
integer :: arg
type(subdata), allocatable :: res, res1
allocate(res, res1, source = subdata(arg))
end function
function greeting1 (arg) result(res) ! memory was lost, now OK
character(*) :: arg
Character(:), allocatable :: res
allocate(res, source = arg)
end function
function greeting2 (arg) result(res)
character(5) :: arg
Character(:), allocatable :: res
allocate(res, source = arg)
end function
function greeting3 (arg) result(res)
character(5) :: arg
Character(5), allocatable :: res, res1
allocate(res, res1, source = arg) ! Caused an ICE
if (res1 .ne. res) call abort
end function
subroutine greeting4 (res, arg)
character(8), intent(in) :: arg
Character(8), allocatable, intent(out) :: res
allocate(res, source = arg) ! Caused an ICE
end subroutine
end
! { dg-final { scan-tree-dump-times "builtin_malloc" 20 "original" } }
! { dg-final { scan-tree-dump-times "builtin_free" 21 "original" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment