ping..... Thanks, Dehao
On Fri, Aug 10, 2012 at 8:38 PM, Dehao Chen <de...@google.com> wrote: > New patch attached. > > Bootstrapped and passed GCC regression tests. > > Ok for trunk? > > Thanks, > Dehao > > gcc/ChangeLog > 2012-08-07 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_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 <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 **** > --- 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);