aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@adacore.com>2014-06-18 09:00:22 +0000
committerOlivier Hainque <hainque@gcc.gnu.org>2014-06-18 09:00:22 +0000
commita5852beabcf2e8c5bdfd6143191df3183c0db590 (patch)
treefff1f2d130096327303f4f0437fbb8ca6589d52a /gcc
parent68f6df73324a1389bce336d55ae94aa58f519997 (diff)
downloadgcc-a5852beabcf2e8c5bdfd6143191df3183c0db590.zip
gcc-a5852beabcf2e8c5bdfd6143191df3183c0db590.tar.gz
gcc-a5852beabcf2e8c5bdfd6143191df3183c0db590.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gimplify.c25
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gnat.dg/blocklocs.adb26
-rw-r--r--gcc/tree-core.h1
-rw-r--r--gcc/tree.h5
5 files changed, 58 insertions, 3 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 2efc899..3dcb4af 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 cb2984d..c61da63 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 0000000..20ff7b3
--- /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 a176553..c9d43d0 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 4a29aa2..0a334cc 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.