Commit 820055a0 by Dehao Chen Committed by Dehao Chen

tree-eh.c (goto_queue_node): New field.

gcc:
	* 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.

testsuite:
	* g++.dg/debug/dwarf2/deallocator.C: New test.

libjava:
	* testsuite/libjava.lang/sourcelocation.java: New cases.
	* testsuite/libjava.lang/sourcelocation.out: New cases.

From-SVN: r191338
parent 71452ccd
2012-09-14 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.
2012-09-14 David Edelsohn <dje.gcc@gmail.com> 2012-09-14 David Edelsohn <dje.gcc@gmail.com>
* configure: Regenerated. * configure: Regenerated.
......
...@@ -7453,6 +7453,15 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, ...@@ -7453,6 +7453,15 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
gimple_seq eval, cleanup; gimple_seq eval, cleanup;
gimple try_; gimple try_;
/* Calls to destructors are generated automatically in FINALLY/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 FINALLY/CATCH
block, and will automatically reset to its original value by the
end of gimplify_expr. */
input_location = UNKNOWN_LOCATION;
eval = cleanup = NULL; eval = cleanup = NULL;
gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval); gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup); gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
......
2012-09-14 Dehao Chen <dehao@google.com>
* g++.dg/debug/dwarf2/deallocator.C: New test.
2012-09-14 Joseph Myers <joseph@codesourcery.com> 2012-09-14 Joseph Myers <joseph@codesourcery.com>
PR c/54552 PR c/54552
......
// 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 "deallocator.C:28" } }
...@@ -321,6 +321,7 @@ static bitmap eh_region_may_contain_throw_map; ...@@ -321,6 +321,7 @@ static bitmap eh_region_may_contain_throw_map;
struct goto_queue_node struct goto_queue_node
{ {
treemple stmt; treemple stmt;
location_t location;
gimple_seq repl_stmt; gimple_seq repl_stmt;
gimple cont_stmt; gimple cont_stmt;
int index; int index;
...@@ -560,7 +561,8 @@ static void ...@@ -560,7 +561,8 @@ static void
record_in_goto_queue (struct leh_tf_state *tf, record_in_goto_queue (struct leh_tf_state *tf,
treemple new_stmt, treemple new_stmt,
int index, int index,
bool is_label) bool is_label,
location_t location)
{ {
size_t active, size; size_t active, size;
struct goto_queue_node *q; struct goto_queue_node *q;
...@@ -583,6 +585,7 @@ record_in_goto_queue (struct leh_tf_state *tf, ...@@ -583,6 +585,7 @@ record_in_goto_queue (struct leh_tf_state *tf,
memset (q, 0, sizeof (*q)); memset (q, 0, sizeof (*q));
q->stmt = new_stmt; q->stmt = new_stmt;
q->index = index; q->index = index;
q->location = location;
q->is_label = is_label; q->is_label = is_label;
} }
...@@ -590,7 +593,8 @@ record_in_goto_queue (struct leh_tf_state *tf, ...@@ -590,7 +593,8 @@ record_in_goto_queue (struct leh_tf_state *tf,
TF is not null. */ TF is not null. */
static void 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; int index;
treemple temp, new_stmt; treemple temp, new_stmt;
...@@ -629,7 +633,7 @@ record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label) ...@@ -629,7 +633,7 @@ record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label)
since with a GIMPLE_COND we have an easy access to the then/else since with a GIMPLE_COND we have an easy access to the then/else
labels. */ labels. */
new_stmt = stmt; 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 /* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a try_finally
...@@ -649,19 +653,22 @@ maybe_record_in_goto_queue (struct leh_state *state, gimple stmt) ...@@ -649,19 +653,22 @@ maybe_record_in_goto_queue (struct leh_state *state, gimple stmt)
{ {
case GIMPLE_COND: case GIMPLE_COND:
new_stmt.tp = gimple_op_ptr (stmt, 2); 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); 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; break;
case GIMPLE_GOTO: case GIMPLE_GOTO:
new_stmt.g = stmt; 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; break;
case GIMPLE_RETURN: case GIMPLE_RETURN:
tf->may_return = true; tf->may_return = true;
new_stmt.g = stmt; 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; break;
default: default:
...@@ -866,13 +873,19 @@ frob_into_branch_around (gimple tp, eh_region region, tree over) ...@@ -866,13 +873,19 @@ frob_into_branch_around (gimple tp, eh_region region, tree over)
Make sure to record all new labels found. */ Make sure to record all new labels found. */
static gimple_seq 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 region = NULL;
gimple_seq new_seq; gimple_seq new_seq;
gimple_stmt_iterator gsi;
new_seq = copy_gimple_seq_and_replace_locals (seq); 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) if (outer_state->tf)
region = outer_state->tf->try_finally_expr; region = outer_state->tf->try_finally_expr;
collect_finally_tree_1 (new_seq, region); collect_finally_tree_1 (new_seq, region);
...@@ -967,7 +980,8 @@ honor_protect_cleanup_actions (struct leh_state *outer_state, ...@@ -967,7 +980,8 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else)); gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else));
} }
else if (this_state) 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); finally_may_fallthru = gimple_seq_may_fallthru (finally);
/* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
...@@ -1184,7 +1198,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf) ...@@ -1184,7 +1198,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
if (tf->may_fallthru) 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); lower_eh_constructs_1 (state, &seq);
gimple_seq_add_seq (&new_stmt, seq); gimple_seq_add_seq (&new_stmt, seq);
...@@ -1200,7 +1214,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf) ...@@ -1200,7 +1214,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
if (eh_else) if (eh_else)
seq = gimple_eh_else_e_body (eh_else); seq = gimple_eh_else_e_body (eh_else);
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); lower_eh_constructs_1 (state, &seq);
emit_post_landing_pad (&eh_seq, tf->region); emit_post_landing_pad (&eh_seq, tf->region);
...@@ -1250,7 +1264,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf) ...@@ -1250,7 +1264,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
x = gimple_build_label (lab); x = gimple_build_label (lab);
gimple_seq_add_stmt (&new_stmt, x); 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); lower_eh_constructs_1 (state, &seq);
gimple_seq_add_seq (&new_stmt, seq); gimple_seq_add_seq (&new_stmt, seq);
......
2012-09-14 Dehao Chen <dehao@google.com>
* testsuite/libjava.lang/sourcelocation.java: New cases.
* testsuite/libjava.lang/sourcelocation.out: New cases.
2012-09-14 David Edelsohn <dje.gcc@gmail.com> 2012-09-14 David Edelsohn <dje.gcc@gmail.com>
* configure: Regenerated. * configure: Regenerated.
......
/* This test should test the source location attribution.
We print the line number of different parts of the program to make sure
that the source code attribution is correct.
To make this test pass, one need to have up-to-date addr2line installed
to parse the dwarf4 data format.
*/
public class sourcelocation {
public static void main(String args[]) {
try {
System.out.println(new Exception().getStackTrace()[0].getLineNumber());
throw new Exception();
} catch (Exception e) {
System.out.println(new Exception().getStackTrace()[0].getLineNumber());
} finally {
System.out.println(new Exception().getStackTrace()[0].getLineNumber());
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment