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

--- Comment #3 from Tobias Burnus <burnus at gcc dot gnu.org> 2012-05-18 
17:05:57 UTC ---
(In reply to comment #0)
>     x=filler(filler(y, real(2*i)), real(i))

That line should call "filler" twice, however, it is called trice! There are
two "atmps" - on the second is properly freed. If one does a backtrace in
gfc_trans_create_temp_array, one sees:

#0                        gfc_trans_create_temp_array at  trans-array.c:986
#1  0x00000000005f009f in gfc_conv_procedure_call     at  trans-expr.c:4326 <<<
...
#8  0x00000000005f0dce in gfc_conv_function_expr      at  trans-expr.c:4885
#9  0x00000000005d0999 in gfc_add_loop_ss_code        at  trans-array.c:2514
#10 0x00000000005d1626 in gfc_conv_loop_setup         at  trans-array.c:4542
#11 0x00000000005f671b in realloc_lhs_loop_for_fcn_call at trans-expr.c:6342
#12                       gfc_trans_arrayfunc_assign  at  trans-expr.c:6522 
<<<


#0                        gfc_trans_create_temp_array at  trans-array.c:986
#1  0x00000000005f009f in gfc_conv_procedure_call     at  trans-expr.c:4326 
<<<
...
#8  0x00000000005f0dce in gfc_conv_function_expr      at  trans-expr.c:4885
#9  0x00000000005f61fd in gfc_trans_arrayfunc_assign  at  trans-expr.c:6532 <<<


trans-expr.c has in gfc_trans_arrayfunc_assign the following, which looks fine:

  6517      {
  6518        realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
  6519  
  6520        if (!expr2->value.function.isym)
  6521          {
  6522            realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss,
&loop);
  6523            ss->is_alloc_lhs = 1;
  6524          }
  6525        else
  6526          fcncall_realloc_result (&se, expr1->rank);
  6527      }
  6528  
  6529    gfc_conv_function_expr (&se, expr2);
  6530    gfc_add_block_to_block (&se.pre, &se.post);
  6531  
  6532    return gfc_finish_block (&se.pre);
  6533  }

However, in gfc_conv_procedure_call the "if" should evaluate true for the
second call - but it does not! Thus, another temporary array is generated and a
second call is inserted.

  4312            if (gfc_option.flag_realloc_lhs
  4313                  && se->ss && se->ss->is_alloc_lhs)
  4314              {
  4315                gfc_free_interface_mapping (&mapping);
  4316                return has_alternate_specifier;
  4317              }
  4318  
  4319            /* Create a temporary to store the result.  In case the
function
  4320               returns a pointer, the temporary will be a shallow copy
and
  4321               mustn't be deallocated.  */
  4322            callee_alloc = sym->attr.allocatable || sym->attr.pointer;
  4323            gfc_trans_create_temp_array (&se->pre, &se->post, se->ss,
  4324                                         tmp, NULL_TREE, false,
  4325                                         !sym->attr.pointer,
callee_alloc,
  4326                                         &se->ss->info->expr->where);

Reply via email to