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,

Reply via email to