This is the mail archive of the gcc-patches@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]

Re: [PATCH] Set correct source location for deallocator calls


ping....

Thanks,
Dehao

On Sat, Aug 18, 2012 at 6:02 AM, Dehao Chen <dehao@google.com> wrote:
> Hi, Richard,
>
> Thanks for the review. I've addressed most of the issues except the
> java unittest (see comments below). The new patch is attached in the
> end of this email.
>
> Thanks,
> Dehao
>
> On Fri, Aug 17, 2012 at 8:47 AM, Richard Henderson <rth@redhat.com> wrote:
>> On 2012-08-10 20:38, Dehao Chen wrote:
>>> + // { dg-final { scan-assembler "1 28 0" } }
>>
>> This test case isn't going to work except with dwarf2, and with gas.
>> You can use -dA so that you can scan for file.c:line.  There are
>> other examples in the testsuite.
>
> Done.
>>
>> This doesn't belong in guality.  It belongs in g++.dg/debug/.
>
> Done.
>
>> It would be nice if you could add a java testcase to see that it
>> doesn't regress.
>
> I spend a whole day working on this, but find it very difficult to add
> such a java test because:
>
> * First, libjava testsuits are all runtime tests, i.e., it compiles
> the byte code to native code, execute it, and compares the output to
> expected output. There is no way to scan the assembly.
> * Though there is a way to derive the line number at runtime in java
> (using Exception().getStackTrace()), this method only works on VM, and
> the gcj generated native code does not get the lineno.
>
> Any suggestions on this?
>
>>
>>> ! record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt,
>>> tree label,
>>> !                         location_t location)
>>
>> BTW, for the future, please fix your mailer to not wrap lines.
>
> Okay, I'll try. The problem is that we have to send mail in plain txt.
> And in "plain text mode" gmail wraps each line to 80 characters and
> wouldn't allow you change that...
>
>> I'll quibble with the wording here.  It reads as if we want to force
>> all calls to have UNKNOWN_LOC, whereas all we want is to prevent any
>> calls that already have UNKNOWN_LOC from gaining input_loc via gimplify_call_expr.
>
> Done.
>
> New Patch:
> gcc/ChangeLog
>          * tree-eh.c (goto_queue_node): New field.
>         (record_in_goto_queue): New parameter.
>         (record_in_goto_queue_label): New parameter.
>         (lower_try_finally_dup_block): New parameter.
>         (maybe_record_in_goto_queue): Update source location.
>         (lower_try_finally_copy): Likewise.
>         (honor_protect_cleanup_actions): Likewise.
>         * gimplify.c (gimplify_expr): Reset the location to unknown.
>
> gcc/testsuite/ChangeLog
> 2012-08-07  Dehao Chen  <dehao@google.com>
>
>         * g++.dg/debug/dwarf2/deallocator.C: New test.
>
> Index: gcc/testsuite/g++.dg/debug/dwarf2/deallocator.C
> ===================================================================
> --- gcc/testsuite/g++.dg/debug/dwarf2/deallocator.C     (revision 0)
> +++ gcc/testsuite/g++.dg/debug/dwarf2/deallocator.C     (revision 0)
> @@ -0,0 +1,33 @@
> +// Test that debug info generated for auto-inserted deallocator is
> +// correctly attributed.
> +// This patch scans for the lineno directly from assembly, which may
> +// differ between different architectures. Because it mainly tests
> +// FE generated debug info, without losing generality, only x86
> +// assembly is scanned in this test.
> +// { dg-do compile { target { i?86-*-* x86_64-*-* } } }
> +// { dg-options "-O2 -fno-exceptions -g -dA" }
> +
> +struct t {
> +  t ();
> +  ~t ();
> +  void foo();
> +  void bar();
> +};
> +
> +int bar();
> +
> +void foo(int i)
> +{
> +  for (int j = 0; j < 10; j++)
> +    {
> +      t test;
> +      test.foo();
> +      if (i + j)
> +       {
> +         test.bar();
> +         return;
> +       }
> +    }
> +  return;
> +}
> +// { dg-final { scan-assembler "1 28 0" } }
> Index: gcc/tree-eh.c
> ===================================================================
> --- gcc/tree-eh.c       (revision 190209)
> +++ gcc/tree-eh.c       (working copy)
> @@ -321,6 +321,7 @@
>  struct goto_queue_node
>  {
>    treemple stmt;
> +  location_t location;
>    gimple_seq repl_stmt;
>    gimple cont_stmt;
>    int index;
> @@ -560,7 +561,8 @@
>  record_in_goto_queue (struct leh_tf_state *tf,
>                        treemple new_stmt,
>                        int index,
> -                      bool is_label)
> +                      bool is_label,
> +                     location_t location)
>  {
>    size_t active, size;
>    struct goto_queue_node *q;
> @@ -583,6 +585,7 @@
>    memset (q, 0, sizeof (*q));
>    q->stmt = new_stmt;
>    q->index = index;
> +  q->location = location;
>    q->is_label = is_label;
>  }
>
> @@ -590,7 +593,8 @@
>     TF is not null.  */
>
>  static void
> -record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label)
> +record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label,
> +                           location_t location)
>  {
>    int index;
>    treemple temp, new_stmt;
> @@ -629,7 +633,7 @@
>       since with a GIMPLE_COND we have an easy access to the then/else
>       labels. */
>    new_stmt = stmt;
> -  record_in_goto_queue (tf, new_stmt, index, true);
> +  record_in_goto_queue (tf, new_stmt, index, true, location);
>  }
>
>  /* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a try_finally
> @@ -649,19 +653,22 @@
>      {
>      case GIMPLE_COND:
>        new_stmt.tp = gimple_op_ptr (stmt, 2);
> -      record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt));
> +      record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt),
> +                                 EXPR_LOCATION (*new_stmt.tp));
>        new_stmt.tp = gimple_op_ptr (stmt, 3);
> -     record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt));
> +      record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt),
> +                                 EXPR_LOCATION (*new_stmt.tp));
>        break;
>      case GIMPLE_GOTO:
>        new_stmt.g = stmt;
> -      record_in_goto_queue_label (tf, new_stmt, gimple_goto_dest (stmt));
> +      record_in_goto_queue_label (tf, new_stmt, gimple_goto_dest (stmt),
> +                                 gimple_location (stmt));
>        break;
>
>      case GIMPLE_RETURN:
>        tf->may_return = true;
>        new_stmt.g = stmt;
> -      record_in_goto_queue (tf, new_stmt, -1, false);
> +      record_in_goto_queue (tf, new_stmt, -1, false, gimple_location (stmt));
>        break;
>
>      default:
> @@ -866,13 +873,19 @@
>     Make sure to record all new labels found.  */
>
>  static gimple_seq
> -lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state)
> +lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state,
> +                            location_t loc)
>  {
>    gimple region = NULL;
>    gimple_seq new_seq;
> +  gimple_stmt_iterator gsi;
>
>    new_seq = copy_gimple_seq_and_replace_locals (seq);
>
> +  for (gsi = gsi_start (new_seq); !gsi_end_p (gsi); gsi_next (&gsi))
> +    if (gimple_location (gsi_stmt (gsi)) == UNKNOWN_LOCATION)
> +      gimple_set_location (gsi_stmt (gsi), loc);
> +
>    if (outer_state->tf)
>      region = outer_state->tf->try_finally_expr;
>    collect_finally_tree_1 (new_seq, region);
> @@ -967,7 +980,8 @@
>        gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else));
>      }
>    else if (this_state)
> -    finally = lower_try_finally_dup_block (finally, outer_state);
> +    finally = lower_try_finally_dup_block (finally, outer_state,
> +                                          UNKNOWN_LOCATION);
>    finally_may_fallthru = gimple_seq_may_fallthru (finally);
>
>    /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
> @@ -1184,7 +1198,7 @@
>
>    if (tf->may_fallthru)
>      {
> -      seq = lower_try_finally_dup_block (finally, state);
> +      seq = lower_try_finally_dup_block (finally, state, tf_loc);
>        lower_eh_constructs_1 (state, &seq);
>        gimple_seq_add_seq (&new_stmt, seq);
>
> @@ -1200,7 +1214,7 @@
>        if (eh_else)
>         seq = gimple_eh_else_e_body (eh_else);
>        else
> -       seq = lower_try_finally_dup_block (finally, state);
> +       seq = lower_try_finally_dup_block (finally, state, tf_loc);
>        lower_eh_constructs_1 (state, &seq);
>
>        emit_post_landing_pad (&eh_seq, tf->region);
> @@ -1250,7 +1264,7 @@
>           x = gimple_build_label (lab);
>            gimple_seq_add_stmt (&new_stmt, x);
>
> -         seq = lower_try_finally_dup_block (finally, state);
> +         seq = lower_try_finally_dup_block (finally, state, q->location);
>           lower_eh_constructs_1 (state, &seq);
>            gimple_seq_add_seq (&new_stmt, seq);
>
> Index: gcc/gimplify.c
> ===================================================================
> --- gcc/gimplify.c      (revision 190209)
> +++ gcc/gimplify.c      (working copy)
> @@ -7434,6 +7434,15 @@
>             gimple_seq eval, cleanup;
>             gimple try_;
>
> +           /* Calls to destructors are generated automatically in FINALL/CATCH
> +              block. They should have location as UNKNOWN_LOCATION. However,
> +              gimplify_call_expr will reset these call stmts to input_location
> +              if it finds stmt's location is unknown. To prevent resetting for
> +              destructors, we set the input_location to unknown.
> +              Note that this only affects the destructor calls in FINALL/CATCH
> +              block, and will automatically reset to its original value by the
> +              end of gimplify_expr.  */
> +           input_location = UNKNOWN_LOCATION;
>             eval = cleanup = NULL;
>             gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
>             gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);


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