gcc:
authordehao <dehao@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 Sep 2012 00:41:53 +0000 (00:41 +0000)
committerdehao <dehao@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 Sep 2012 00:41:53 +0000 (00:41 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191338 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/dwarf2/deallocator.C [new file with mode: 0644]
gcc/tree-eh.c
libjava/ChangeLog
libjava/testsuite/libjava.lang/sourcelocation.jar [new file with mode: 0644]
libjava/testsuite/libjava.lang/sourcelocation.java [new file with mode: 0644]
libjava/testsuite/libjava.lang/sourcelocation.out [new file with mode: 0644]

index 1c00bf6..cc1ff19 100644 (file)
@@ -1,3 +1,14 @@
+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>
 
        * configure: Regenerated.
index f73ac1e..3188316 100644 (file)
@@ -7453,6 +7453,15 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
            gimple_seq eval, cleanup;
            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;
            gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
            gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
index cd1c5fa..9a2ef73 100644 (file)
@@ -1,3 +1,7 @@
+2012-09-14  Dehao Chen  <dehao@google.com>
+
+       * g++.dg/debug/dwarf2/deallocator.C: New test.
+
 2012-09-14  Joseph Myers  <joseph@codesourcery.com>
 
        PR c/54552
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/deallocator.C b/gcc/testsuite/g++.dg/debug/dwarf2/deallocator.C
new file mode 100644 (file)
index 0000000..eab38a3
--- /dev/null
@@ -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 "deallocator.C:28" } }
index ec74d9d..65f85c9 100644 (file)
@@ -321,6 +321,7 @@ static bitmap eh_region_may_contain_throw_map;
 struct goto_queue_node
 {
   treemple stmt;
+  location_t location;
   gimple_seq repl_stmt;
   gimple cont_stmt;
   int index;
@@ -560,7 +561,8 @@ static void
 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 @@ record_in_goto_queue (struct leh_tf_state *tf,
   memset (q, 0, sizeof (*q));
   q->stmt = new_stmt;
   q->index = index;
+  q->location = location;
   q->is_label = is_label;
 }
 
@@ -590,7 +593,8 @@ record_in_goto_queue (struct leh_tf_state *tf,
    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 @@ 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
      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 @@ maybe_record_in_goto_queue (struct leh_state *state, gimple stmt)
     {
     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 @@ frob_into_branch_around (gimple tp, eh_region region, tree over)
    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 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
       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 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
 
   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 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
       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 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
          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 25d6829..69b13d7 100644 (file)
@@ -1,3 +1,8 @@
+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>
 
        * configure: Regenerated.
diff --git a/libjava/testsuite/libjava.lang/sourcelocation.jar b/libjava/testsuite/libjava.lang/sourcelocation.jar
new file mode 100644 (file)
index 0000000..90f38f4
Binary files /dev/null and b/libjava/testsuite/libjava.lang/sourcelocation.jar differ
diff --git a/libjava/testsuite/libjava.lang/sourcelocation.java b/libjava/testsuite/libjava.lang/sourcelocation.java
new file mode 100644 (file)
index 0000000..6cf1e40
--- /dev/null
@@ -0,0 +1,18 @@
+/* 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());
+    }
+  }
+}
diff --git a/libjava/testsuite/libjava.lang/sourcelocation.out b/libjava/testsuite/libjava.lang/sourcelocation.out
new file mode 100644 (file)
index 0000000..781c91b
--- /dev/null
@@ -0,0 +1,3 @@
+10
+13
+15