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,