diff --git a/ChangeLog b/ChangeLog index fc6a3365c26..af5dc1b7388 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2014-06-18 Olivier Hainque + + * 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 * config-ml.in: Robustify ac_configure_args parsing. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 2efc8992008..3dcb4affe3f 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 cb2984d8e94..c61da63182f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-06-18 Olivier Hainque + + * gnat.dg/blocklocs.adb: New test. + 2014-06-18 Evgeny Stupachenko 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 00000000000..20ff7b30135 --- /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 a17655389b4..c9d43d0732e 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 *nonlocalized_vars; diff --git a/gcc/tree.h b/gcc/tree.h index 4a29aa2776d..0a334cc511d 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.