From a5852beabcf2e8c5bdfd6143191df3183c0db590 Mon Sep 17 00:00:00 2001
From: Olivier Hainque <hainque@adacore.com>
Date: Wed, 18 Jun 2014 09:00:22 +0000
Subject: [PATCH] improve sloc assignment on bind_expr entry/exit code

2014-06-18  Olivier Hainque <hainque@adacore.com>

        improve sloc assignment on bind_expr entry/exit code

        gcc/
        * tree-core.h (tree_block): Add an "end_locus" field, allowing
        memorization of the end of block source location.
        * tree.h (BLOCK_SOURCE_END_LOCATION): New accessor.
        * gimplify.c (gimplify_bind_expr): Propagate the block start and
        end source location info we have on the block entry/exit code we
        generate.

        testsuite/
        * gnat.dg/blocklocs.adb: New test.

From-SVN: r211773
---
 ChangeLog                           |  9 +++++++++
 gcc/gimplify.c                      | 25 ++++++++++++++++++++++---
 gcc/testsuite/ChangeLog             |  4 ++++
 gcc/testsuite/gnat.dg/blocklocs.adb | 26 ++++++++++++++++++++++++++
 gcc/tree-core.h                     |  1 +
 gcc/tree.h                          |  5 +++++
 6 files changed, 67 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gnat.dg/blocklocs.adb

diff --git a/ChangeLog b/ChangeLog
index fc6a3365c26e..af5dc1b7388c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2014-06-18  Olivier Hainque  <hainque@adacore.com>
+
+	* tree-core.h (tree_block): Add an "end_locus" field, allowing
+	memorization of the end of block source location.
+	* tree.h (BLOCK_SOURCE_END_LOCATION): New accessor.
+	* gimplify.c (gimplify_bind_expr): Propagate the block start and
+	end source location info we have on the block entry/exit code we
+	generate.
+
 2014-06-13  Thomas Schwinge  <thomas@codesourcery.com>
 
 	* config-ml.in: Robustify ac_configure_args parsing.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 2efc8992008c..3dcb4affe3f5 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1047,6 +1047,7 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
   gimple gimple_bind;
   gimple_seq body, cleanup;
   gimple stack_save;
+  location_t start_locus = 0, end_locus = 0;
 
   tree temp = voidify_wrapper_expr (bind_expr, NULL);
 
@@ -1099,6 +1100,19 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
   gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
   gimple_bind_set_body (gimple_bind, body);
 
+  /* Source location wise, the cleanup code (stack_restore and clobbers)
+     belongs to the end of the block, so propagate what we have.  The
+     stack_save operation belongs to the beginning of block, which we can
+     infer from the bind_expr directly if the block has no explicit
+     assignment.  */
+  if (BIND_EXPR_BLOCK (bind_expr))
+    {
+      end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
+      start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
+    }
+  if (start_locus == 0)
+    start_locus = EXPR_LOCATION (bind_expr);
+
   cleanup = NULL;
   stack_save = NULL;
   if (gimplify_ctxp->save_stack)
@@ -1109,6 +1123,9 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
 	 block to achieve this.  */
       build_stack_save_restore (&stack_save, &stack_restore);
 
+      gimple_set_location (stack_save, start_locus);
+      gimple_set_location (stack_restore, end_locus);
+
       gimplify_seq_add_stmt (&cleanup, stack_restore);
     }
 
@@ -1126,10 +1143,12 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
 	  && !is_gimple_reg (t)
 	  && flag_stack_reuse != SR_NONE)
 	{
-	  tree clobber = build_constructor (TREE_TYPE (t),
-					    NULL);
+	  tree clobber = build_constructor (TREE_TYPE (t), NULL);
+	  gimple clobber_stmt;
 	  TREE_THIS_VOLATILE (clobber) = 1;
-	  gimplify_seq_add_stmt (&cleanup, gimple_build_assign (t, clobber));
+	  clobber_stmt = gimple_build_assign (t, clobber);
+	  gimple_set_location (clobber_stmt, end_locus);
+	  gimplify_seq_add_stmt (&cleanup, clobber_stmt);
 	}
     }
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cb2984d8e94e..c61da63182f7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2014-06-18  Olivier Hainque  <hainque@adacore.com>
+
+	* gnat.dg/blocklocs.adb: New test.
+
 2014-06-18  Evgeny Stupachenko  <evstupac@gmail.com>
 
 	PR tree-optimization/52252
diff --git a/gcc/testsuite/gnat.dg/blocklocs.adb b/gcc/testsuite/gnat.dg/blocklocs.adb
new file mode 100644
index 000000000000..20ff7b301356
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/blocklocs.adb
@@ -0,0 +1,26 @@
+-- { dg-do compile { target *-*-linux* } }
+-- { dg-options "-gdwarf-2" }
+
+procedure Blocklocs (Choice : Integer; N : in out Integer) is
+begin
+   if Choice > 0 then
+      declare -- line 7
+         S : String (1 .. N * 2);
+         pragma Volatile (S);
+      begin
+	 S := (others => 'B');
+      end;    -- line 12
+   else
+      declare -- line 14
+	 S : String (1 .. N );
+	 pragma Volatile (S);
+      begin
+	 S := (others => '1');
+      end;    -- line 19
+   end if;
+end;
+   
+-- { dg-final { scan-assembler "loc 1 7" } }
+-- { dg-final { scan-assembler "loc 1 12" } }
+-- { dg-final { scan-assembler "loc 1 14" } }
+-- { dg-final { scan-assembler "loc 1 19" } }
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index a17655389b44..c9d43d0732ef 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1253,6 +1253,7 @@ struct GTY(()) tree_block {
   unsigned block_num : 31;
 
   location_t locus;
+  location_t end_locus;
 
   tree vars;
   vec<tree, va_gc> *nonlocalized_vars;
diff --git a/gcc/tree.h b/gcc/tree.h
index 4a29aa2776d0..0a334cc511df 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1500,6 +1500,11 @@ extern void protected_set_expr_location (tree, location_t);
 
 #define BLOCK_SOURCE_LOCATION(NODE) (BLOCK_CHECK (NODE)->block.locus)
 
+/* This gives the location of the end of the block, useful to attach
+   code implicitly generated for outgoing paths.  */
+
+#define BLOCK_SOURCE_END_LOCATION(NODE) (BLOCK_CHECK (NODE)->block.end_locus)
+
 /* Define fields and accessors for nodes representing data types.  */
 
 /* See tree.def for documentation of the use of these fields.
-- 
GitLab