Background: There is currently a memory leakage cleanup in the middle
end – and fixing PR 54332 would probably have been also easier without
FE leaks.
I think we should join in an try to remove some leakage - and try to not
introduce new ones.
* * *
Committed: For EXPR_END_PROCEDURE, I have committed one fix as obvious
(-> parse.c). However, I have a test case where parse_contained still
leaks memory, possibly another, similar patch is needed in addition.
* * *
There are also plenty of leaks related to the freeing of gfc_ss. I
attached a draft patch (trans-expr.c, trans-intrinsics.c), which is
probably okay, but not yet regtested.
OK with a changelog (and if it regtested)?
Note: The patch is incomplete, e.g. "argss" of gfc_conv_procedure_call
is not (or not always) freed. Ditto for rss of gfc_trans_assignment_1;
ditto for lss and rss of gfc_trans_pointer_assignment
* * * * * * * * * * * *
Additionally, there is a memory leak when generating more than one
procedure per TU: The memory which is allocated but not freed
gfc_generate_function_code -> (generate_coarray_init or
trans_function_start) -> init_function_start -> prepare_function_start
-> init_emit
The memory should be feed via (backend_init_target or
lang_dependent_init_target) -> expand_dummy_function_end ->
free_after_compilation
The latter seems to operate on "cfun" – hence, it only frees the last
"cfun" and not all.
However, despite some longer debugging (e.g. using a main program, which
calls create_main_function), I failed to find the problem.
* * *
And module.c can also leak plenty of memory ...
Tobias
Index: gcc/fortran/ChangeLog
===================================================================
--- gcc/fortran/ChangeLog (Revision 190574)
+++ gcc/fortran/ChangeLog (Arbeitskopie)
@@ -1,3 +1,8 @@
+2012-08-21 Tobias Burnus <bur...@net-b.de>
+
+ * parse.c (parse_contained): Include EXEC_END_PROCEDURE
+ in ns->code to make sure the gfc_code is freed.
+
2012-08-20 Tobias Burnus <bur...@net-b.de>
PR fortran/54301
Index: gcc/fortran/parse.c
===================================================================
--- gcc/fortran/parse.c (Revision 190574)
+++ gcc/fortran/parse.c (Arbeitskopie)
@@ -4075,6 +4075,7 @@ parse_contained (int module)
case ST_END_PROGRAM:
case ST_END_SUBROUTINE:
accept_statement (st);
+ gfc_current_ns->code = s1.head;
break;
default:
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 4f7d026..cfb0862 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -533,6 +533,7 @@ gfc_copy_class_to_class (tree from, tree to, tree nelems)
loop.to[0] = nelems;
gfc_trans_scalarizing_loops (&loop, &loopbody);
gfc_add_block_to_block (&body, &loop.pre);
+ gfc_cleanup_loop (&loop);
tmp = gfc_finish_block (&body);
}
else
@@ -6770,6 +6771,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
if (!expr2->value.function.isym)
{
realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
+ gfc_cleanup_loop (&loop);
ss->is_alloc_lhs = 1;
}
else
@@ -6778,6 +6780,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
gfc_conv_function_expr (&se, expr2);
gfc_add_block_to_block (&se.pre, &se.post);
+ gfc_free_ss (se.ss);
return gfc_finish_block (&se.pre);
}
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index fac29c7..d0aebe9 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -1328,6 +1328,7 @@ gfc_conv_intrinsic_rank (gfc_se *se, gfc_expr *expr)
argse.descriptor_only = 1;
gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr, ss);
+ gfc_free_ss (ss);
gfc_add_block_to_block (&se->pre, &argse.pre);
gfc_add_block_to_block (&se->post, &argse.post);