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


New patch attached.

Bootstrapped and passed GCC regression tests.

Ok for trunk?

Thanks,
Dehao

gcc/ChangeLog
2012-08-07  Dehao Chen  <dehao@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_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/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 ****
--- 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 190209)
--- gcc/tree-eh.c	(working copy)
*************** static bitmap eh_region_may_contain_thro
*** 321,326 ****
--- 321,327 ----
  struct goto_queue_node
  {
    treemple stmt;
+   location_t location;
    gimple_seq repl_stmt;
    gimple cont_stmt;
    int index;
*************** static void
*** 560,566 ****
  record_in_goto_queue (struct leh_tf_state *tf,
                        treemple new_stmt,
                        int index,
!                       bool is_label)
  {
    size_t active, size;
    struct goto_queue_node *q;
--- 561,568 ----
  record_in_goto_queue (struct leh_tf_state *tf,
                        treemple new_stmt,
                        int index,
!                       bool is_label,
! 		      location_t location)
  {
    size_t active, size;
    struct goto_queue_node *q;
*************** record_in_goto_queue (struct leh_tf_stat
*** 583,588 ****
--- 585,591 ----
    memset (q, 0, sizeof (*q));
    q->stmt = new_stmt;
    q->index = index;
+   q->location = location;
    q->is_label = is_label;
  }

*************** record_in_goto_queue (struct leh_tf_stat
*** 590,596 ****
     TF is not null.  */

  static void
! record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt,
tree label)
  {
    int index;
    treemple temp, new_stmt;
--- 593,600 ----
     TF is not null.  */

  static void
! record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt,
tree label,
! 			    location_t location)
  {
    int index;
    treemple temp, new_stmt;
*************** record_in_goto_queue_label (struct leh_t
*** 629,635 ****
       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);
  }

  /* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a
try_finally
--- 633,639 ----
       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, location);
  }

  /* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a
try_finally
*************** maybe_record_in_goto_queue (struct leh_s
*** 649,667 ****
      {
      case GIMPLE_COND:
        new_stmt.tp = gimple_op_ptr (stmt, 2);
!       record_in_goto_queue_label (tf, new_stmt,
gimple_cond_true_label (stmt));
        new_stmt.tp = gimple_op_ptr (stmt, 3);
!       record_in_goto_queue_label (tf, new_stmt,
gimple_cond_false_label (stmt));
        break;
      case GIMPLE_GOTO:
        new_stmt.g = stmt;
!       record_in_goto_queue_label (tf, new_stmt, gimple_goto_dest (stmt));
        break;

      case GIMPLE_RETURN:
        tf->may_return = true;
        new_stmt.g = stmt;
!       record_in_goto_queue (tf, new_stmt, -1, false);
        break;

      default:
--- 653,674 ----
      {
      case GIMPLE_COND:
        new_stmt.tp = gimple_op_ptr (stmt, 2);
!       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),
! 				  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),
! 				  gimple_location (stmt));
        break;

      case GIMPLE_RETURN:
        tf->may_return = true;
        new_stmt.g = stmt;
!       record_in_goto_queue (tf, new_stmt, -1, false, gimple_location (stmt));
        break;

      default:
*************** frob_into_branch_around (gimple tp, eh_r
*** 866,878 ****
     Make sure to record all new labels found.  */

  static gimple_seq
! lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state)
  {
    gimple region = NULL;
    gimple_seq new_seq;

    new_seq = copy_gimple_seq_and_replace_locals (seq);

    if (outer_state->tf)
      region = outer_state->tf->try_finally_expr;
    collect_finally_tree_1 (new_seq, region);
--- 873,891 ----
     Make sure to record all new labels found.  */

  static gimple_seq
! 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);
*************** honor_protect_cleanup_actions (struct le
*** 967,973 ****
        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_may_fallthru = gimple_seq_may_fallthru (finally);

    /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
--- 980,987 ----
        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,
! 					   UNKNOWN_LOCATION);
    finally_may_fallthru = gimple_seq_may_fallthru (finally);

    /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
*************** lower_try_finally_copy (struct leh_state
*** 1184,1190 ****

    if (tf->may_fallthru)
      {
!       seq = lower_try_finally_dup_block (finally, state);
        lower_eh_constructs_1 (state, &seq);
        gimple_seq_add_seq (&new_stmt, seq);

--- 1198,1204 ----

    if (tf->may_fallthru)
      {
!       seq = lower_try_finally_dup_block (finally, state, tf_loc);
        lower_eh_constructs_1 (state, &seq);
        gimple_seq_add_seq (&new_stmt, seq);

*************** lower_try_finally_copy (struct leh_state
*** 1200,1206 ****
        if (eh_else)
  	seq = gimple_eh_else_e_body (eh_else);
        else
! 	seq = lower_try_finally_dup_block (finally, state);
        lower_eh_constructs_1 (state, &seq);

        emit_post_landing_pad (&eh_seq, tf->region);
--- 1214,1220 ----
        if (eh_else)
  	seq = gimple_eh_else_e_body (eh_else);
        else
! 	seq = lower_try_finally_dup_block (finally, state, tf_loc);
        lower_eh_constructs_1 (state, &seq);

        emit_post_landing_pad (&eh_seq, tf->region);
*************** lower_try_finally_copy (struct leh_state
*** 1250,1256 ****
  	  x = gimple_build_label (lab);
            gimple_seq_add_stmt (&new_stmt, x);

! 	  seq = lower_try_finally_dup_block (finally, state);
  	  lower_eh_constructs_1 (state, &seq);
            gimple_seq_add_seq (&new_stmt, seq);

--- 1264,1270 ----
  	  x = gimple_build_label (lab);
            gimple_seq_add_stmt (&new_stmt, x);

! 	  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)
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 7434,7439 ****
--- 7434,7447 ----
  	    gimple_seq eval, cleanup;
  	    gimple try_;

+ 	    /* For call expressions inside FINALL/CATCH block, if its location
+ 	       is unknown, gimplify_call_expr will set it to input_location.
+ 	       However, these calls are automatically generated to destructors.
+ 	       And they may be cloned to many places. In this case, we will
+ 	       set the location for them in tree-eh.c. But to ensure that EH
+ 	       does the right job, we first need mark their location as
+ 	       UNKNOWN_LOCATION.  */
+ 	    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]