This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug fortran/53389] [4.6/4.7/4.8 Regression] -frealloc-lhs: memory leak when assigning array function result to allocatable array, where one of its supplied arguments is itself an array function result


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53389

--- Comment #4 from Tobias Burnus <burnus at gcc dot gnu.org> 2012-05-21 16:16:24 UTC ---
If one duplicates "filler" and renames it to inner/outer with the call:
  x=outer(inner(y, real(2*i)), real(i))

one sees four calls to gfc_conv_procedure_call for: outer, inner, outer, inner.
Everything starts in gfc_trans_arrayfunc_assign:

The first ("outer") is via realloc_lhs_loop_for_fcn_call which has
se->ss->is_alloc_lhs == 1.

The second is for "inner" via gfc_conv_procedure_call -> gfc_conv_function_expr
-> gfc_conv_procedure_call, which uses gfc_trans_create_temp_array.

One then returns to the first call ("outer"), which stops at
gfc_free_interface_mapping as ss->is_alloc_lhs == 1.

Back in gfc_trans_arrayfunc_assign, one now calls gfc_conv_function_expr for
"outer", which again calls via gfc_conv_function_expr the function
gfc_conv_procedure_call for "inner" - which calls gfc_trans_create_temp_array.

Fourth, one is back in gfc_conv_procedure_callwhere one calls
gfc_alloc_allocatable_for_assignment.

Thus, the inner function is evaluated twice.


 * * *


Draft patch: Fixes the issue at hand for allocated/nonallocated "X" (according
to valgrind and dump inspection) and successfully regtests the
realloc_on_assign_*.f* test cases.


--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -2401,6 +2401,11 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss,
bool subscript,
   bool skip_nested = false;
   int n;

+  /* Don't evaluate the arguments for realloc_lhs_loop_for_fcn_call;
otherwise,
+     arguments could get evaluated multiple times.  */
+  if (ss->is_alloc_lhs)
+    return;
+
   outer_loop = outermost_loop (loop);

   /* TODO: This can generate bad code if there are ordering dependencies,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]