Ping...

Richard, could you shed some lights on this?

Thanks,
Dehao

On Mon, Jul 30, 2012 at 8:29 PM, Dehao Chen <de...@google.com> wrote:
> Hi,
>
> This patch fixes the source location for automatically generated calls
> to deallocator. For example:
>
>  19 void foo(int i)
>  20 {
>  21   for (int j = 0; j < 10; j++)
>  22     {
>  23       t test;
>  24       test.foo();
>  25       if (i + j)
>  26         {
>  27           test.bar();
>  28           return;
>  29         }
>  30     }
>  31   return;
>  32 }
>
> The deallocator for "23  t test" is called in two places: Line 28 and
> line 30. However, gcc attributes both callsites to line 30.
>
> Bootstrapped and passed gcc regression tests.
>
> Is it ok for trunk?
>
> Thanks,
> Dehao
>
> gcc/ChangeLog
>
> 2012-07-31  Dehao Chen  <de...@google.com>
>
>         * tree-eh.c (goto_queue_node): New field.
>         (record_in_goto_queue): New parameter.
>         (record_in_goto_queue_label): New parameter.
>         (lower_try_finally_copy): Update source location.
>
> gcc/testsuite/ChangeLog
>
> 2012-07-31  Dehao Chen  <de...@google.com>
>
>         * g++.dg/guality/deallocator.C: New test.
>
> Index: gcc/testsuite/g++.dg/guality/deallocator.C
> ===================================================================
> --- gcc/testsuite/g++.dg/guality/deallocator.C  (revision 0)
> +++ gcc/testsuite/g++.dg/guality/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" }
> +
> +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 189835)
> +++ gcc/tree-eh.c       (working copy)
> @@ -321,6 +321,7 @@
>  struct goto_queue_node
>  {
>    treemple stmt;
> +  enum gimple_code code;
>    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,
> +                     enum gimple_code code)
>  {
>    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->code = code;
>    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,
> +                           enum gimple_code code)
>  {
>    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, code);
>  }
>
>  /* 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),
> +                                 gimple_code (stmt));
>        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),
> +                                 gimple_code (stmt));
>        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_code (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_code (stmt));
>        break;
>
>      default:
> @@ -1234,6 +1241,7 @@
>        for (index = 0; index < return_index + 1; index++)
>         {
>           tree lab;
> +         gimple_stmt_iterator gsi;
>
>           q = labels[index].q;
>           if (! q)
> @@ -1252,6 +1260,11 @@
>
>           seq = lower_try_finally_dup_block (finally, state);
>           lower_eh_constructs_1 (state, &seq);
> +         for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
> +           gimple_set_location (gsi_stmt (gsi),
> +                                q->code == GIMPLE_COND ?
> +                                    EXPR_LOCATION (*q->stmt.tp) :
> +                                    gimple_location (q->stmt.g));
>            gimple_seq_add_seq (&new_stmt, seq);
>
>            gimple_seq_add_stmt (&new_stmt, q->cont_stmt);

Reply via email to