Commit 362db0b2 by Thomas Quinot Committed by Eric Botcazou

trans.c (Handled_Sequence_Of_Statements_to_gnu): If there is no End_Label...

	* gcc-interface/trans.c (Handled_Sequence_Of_Statements_to_gnu): If
	there is no End_Label, attach cleanup actions to the sloc of the HSS
	node instead.
	(Exception_Handler_to_gnu_zcx): Associate cleanup actions with the sloc
	of the handler itself.
	(add_cleanup): Clear column information in sloc of cleanup actions.
	(Sloc_to_locus1): New static function.
	(Sloc_to_locus): Call it.
	(set_expr_location_from_node1): New static function.
	(set_expr_location_from_node): Call it.

From-SVN: r201702
parent 8ec9249b
2013-08-13 Thomas Quinot <quinot@adacore.com>
* gcc-interface/trans.c (Handled_Sequence_Of_Statements_to_gnu): If
there is no End_Label, attach cleanup actions to the sloc of the HSS
node instead.
(Exception_Handler_to_gnu_zcx): Associate cleanup actions with the sloc
of the handler itself.
(add_cleanup): Clear column information in sloc of cleanup actions.
(Sloc_to_locus1): New static function.
(Sloc_to_locus): Call it.
(set_expr_location_from_node1): New static function.
(set_expr_location_from_node): Call it.
2013-08-13 Eric Botcazou <ebotcazou@adacore.com> 2013-08-13 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (Call_to_gnu): Deal with specific conditional * gcc-interface/trans.c (Call_to_gnu): Deal with specific conditional
......
...@@ -257,6 +257,8 @@ static tree pos_to_constructor (Node_Id, tree, Entity_Id); ...@@ -257,6 +257,8 @@ static tree pos_to_constructor (Node_Id, tree, Entity_Id);
static void validate_unchecked_conversion (Node_Id); static void validate_unchecked_conversion (Node_Id);
static tree maybe_implicit_deref (tree); static tree maybe_implicit_deref (tree);
static void set_expr_location_from_node (tree, Node_Id); static void set_expr_location_from_node (tree, Node_Id);
static void set_expr_location_from_node1 (tree, Node_Id, bool);
static bool Sloc_to_locus1 (Source_Ptr, location_t *, bool);
static bool set_end_locus_from_node (tree, Node_Id); static bool set_end_locus_from_node (tree, Node_Id);
static void set_gnu_expr_location_from_node (tree, Node_Id); static void set_gnu_expr_location_from_node (tree, Node_Id);
static int lvalue_required_p (Node_Id, tree, bool, bool, bool); static int lvalue_required_p (Node_Id, tree, bool, bool, bool);
...@@ -4471,6 +4473,10 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node) ...@@ -4471,6 +4473,10 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
tree gnu_result; tree gnu_result;
tree gnu_expr; tree gnu_expr;
Node_Id gnat_temp; Node_Id gnat_temp;
/* Node providing the sloc for the cleanup actions. */
Node_Id gnat_cleanup_loc_node = (Present (End_Label (gnat_node)) ?
End_Label (gnat_node) :
gnat_node);
/* The GCC exception handling mechanism can handle both ZCX and SJLJ schemes /* The GCC exception handling mechanism can handle both ZCX and SJLJ schemes
and we have our own SJLJ mechanism. To call the GCC mechanism, we call and we have our own SJLJ mechanism. To call the GCC mechanism, we call
...@@ -4520,7 +4526,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node) ...@@ -4520,7 +4526,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
/* When we exit this block, restore the saved value. */ /* When we exit this block, restore the saved value. */
add_cleanup (build_call_n_expr (set_jmpbuf_decl, 1, gnu_jmpsave_decl), add_cleanup (build_call_n_expr (set_jmpbuf_decl, 1, gnu_jmpsave_decl),
End_Label (gnat_node)); gnat_cleanup_loc_node);
} }
/* If we are to call a function when exiting this block, add a cleanup /* If we are to call a function when exiting this block, add a cleanup
...@@ -4528,7 +4534,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node) ...@@ -4528,7 +4534,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
so we must register this cleanup after the EH cleanup just above. */ so we must register this cleanup after the EH cleanup just above. */
if (at_end) if (at_end)
add_cleanup (build_call_n_expr (gnat_to_gnu (At_End_Proc (gnat_node)), 0), add_cleanup (build_call_n_expr (gnat_to_gnu (At_End_Proc (gnat_node)), 0),
End_Label (gnat_node)); gnat_cleanup_loc_node);
/* Now build the tree for the declarations and statements inside this block. /* Now build the tree for the declarations and statements inside this block.
If this is SJLJ, set our jmp_buf as the current buffer. */ If this is SJLJ, set our jmp_buf as the current buffer. */
...@@ -4641,14 +4647,18 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node) ...@@ -4641,14 +4647,18 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
/* Now make the TRY_CATCH_EXPR for the block. */ /* Now make the TRY_CATCH_EXPR for the block. */
gnu_result = build2 (TRY_CATCH_EXPR, void_type_node, gnu_result = build2 (TRY_CATCH_EXPR, void_type_node,
gnu_inner_block, gnu_handlers); gnu_inner_block, gnu_handlers);
/* Set a location. We need to find a uniq location for the dispatching /* Set a location. We need to find a unique location for the dispatching
code, otherwise we can get coverage or debugging issues. Try with code, otherwise we can get coverage or debugging issues. Try with
the location of the end label. */ the location of the end label. */
if (Present (End_Label (gnat_node)) if (Present (End_Label (gnat_node))
&& Sloc_to_locus (Sloc (End_Label (gnat_node)), &locus)) && Sloc_to_locus (Sloc (End_Label (gnat_node)), &locus))
SET_EXPR_LOCATION (gnu_result, locus); SET_EXPR_LOCATION (gnu_result, locus);
else else
set_expr_location_from_node (gnu_result, gnat_node); /* Clear column information so that the exception handler of an
implicit transient block does not incorrectly inherit the slocs
of a decision, which would otherwise confuse control flow based
coverage analysis tools. */
set_expr_location_from_node1 (gnu_result, gnat_node, True);
} }
else else
gnu_result = gnu_inner_block; gnu_result = gnu_inner_block;
...@@ -4843,9 +4853,10 @@ Exception_Handler_to_gnu_zcx (Node_Id gnat_node) ...@@ -4843,9 +4853,10 @@ Exception_Handler_to_gnu_zcx (Node_Id gnat_node)
add_stmt_with_node (build_call_n_expr (begin_handler_decl, 1, add_stmt_with_node (build_call_n_expr (begin_handler_decl, 1,
gnu_incoming_exc_ptr), gnu_incoming_exc_ptr),
gnat_node); gnat_node);
/* ??? We don't seem to have an End_Label at hand to set the location. */ /* We don't have an End_Label at hand to set the location of the cleanup
actions, so we use that of the exception handler itself instead. */
add_cleanup (build_call_n_expr (end_handler_decl, 1, gnu_incoming_exc_ptr), add_cleanup (build_call_n_expr (end_handler_decl, 1, gnu_incoming_exc_ptr),
Empty); gnat_node);
add_stmt_list (Statements (gnat_node)); add_stmt_list (Statements (gnat_node));
gnat_poplevel (); gnat_poplevel ();
...@@ -7397,13 +7408,15 @@ mark_visited (tree t) ...@@ -7397,13 +7408,15 @@ mark_visited (tree t)
} }
/* Add GNU_CLEANUP, a cleanup action, to the current code group and /* Add GNU_CLEANUP, a cleanup action, to the current code group and
set its location to that of GNAT_NODE if present. */ set its location to that of GNAT_NODE if present, but with column info
cleared so that conditional branches generated as part of the cleanup
code do not interfere with coverage analysis tools. */
static void static void
add_cleanup (tree gnu_cleanup, Node_Id gnat_node) add_cleanup (tree gnu_cleanup, Node_Id gnat_node)
{ {
if (Present (gnat_node)) if (Present (gnat_node))
set_expr_location_from_node (gnu_cleanup, gnat_node); set_expr_location_from_node1 (gnu_cleanup, gnat_node, True);
append_to_statement_list (gnu_cleanup, &current_stmt_group->cleanups); append_to_statement_list (gnu_cleanup, &current_stmt_group->cleanups);
} }
...@@ -9018,10 +9031,11 @@ maybe_implicit_deref (tree exp) ...@@ -9018,10 +9031,11 @@ maybe_implicit_deref (tree exp)
/* Convert SLOC into LOCUS. Return true if SLOC corresponds to a source code /* Convert SLOC into LOCUS. Return true if SLOC corresponds to a source code
location and false if it doesn't. In the former case, set the Gigi global location and false if it doesn't. In the former case, set the Gigi global
variable REF_FILENAME to the simple debug file name as given by sinput. */ variable REF_FILENAME to the simple debug file name as given by sinput.
If clear_column is True, set column information to 0. */
bool static bool
Sloc_to_locus (Source_Ptr Sloc, location_t *locus) Sloc_to_locus1 (Source_Ptr Sloc, location_t *locus, bool clear_column)
{ {
if (Sloc == No_Location) if (Sloc == No_Location)
return false; return false;
...@@ -9035,7 +9049,7 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus) ...@@ -9035,7 +9049,7 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
{ {
Source_File_Index file = Get_Source_File_Index (Sloc); Source_File_Index file = Get_Source_File_Index (Sloc);
Logical_Line_Number line = Get_Logical_Line_Number (Sloc); Logical_Line_Number line = Get_Logical_Line_Number (Sloc);
Column_Number column = Get_Column_Number (Sloc); Column_Number column = (clear_column ? 0 : Get_Column_Number (Sloc));
struct line_map *map = LINEMAPS_ORDINARY_MAP_AT (line_table, file - 1); struct line_map *map = LINEMAPS_ORDINARY_MAP_AT (line_table, file - 1);
/* We can have zero if pragma Source_Reference is in effect. */ /* We can have zero if pragma Source_Reference is in effect. */
...@@ -9054,20 +9068,36 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus) ...@@ -9054,20 +9068,36 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
return true; return true;
} }
/* Similar to the above, not clearing the column information. */
bool
Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
{
return Sloc_to_locus1 (Sloc, locus, False);
}
/* Similar to set_expr_location, but start with the Sloc of GNAT_NODE and /* Similar to set_expr_location, but start with the Sloc of GNAT_NODE and
don't do anything if it doesn't correspond to a source location. */ don't do anything if it doesn't correspond to a source location. */
static void static void
set_expr_location_from_node (tree node, Node_Id gnat_node) set_expr_location_from_node1 (tree node, Node_Id gnat_node, bool clear_column)
{ {
location_t locus; location_t locus;
if (!Sloc_to_locus (Sloc (gnat_node), &locus)) if (!Sloc_to_locus1 (Sloc (gnat_node), &locus, clear_column))
return; return;
SET_EXPR_LOCATION (node, locus); SET_EXPR_LOCATION (node, locus);
} }
/* Similar to the above, not clearing the column information. */
static void
set_expr_location_from_node (tree node, Node_Id gnat_node)
{
set_expr_location_from_node1 (node, gnat_node, False);
}
/* More elaborate version of set_expr_location_from_node to be used in more /* More elaborate version of set_expr_location_from_node to be used in more
general contexts, for example the result of the translation of a generic general contexts, for example the result of the translation of a generic
GNAT node. */ GNAT node. */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* * * *
* Asm Implementation File * * Asm Implementation File *
* * * *
* Copyright (C) 2011-2012, Free Software Foundation, Inc. * * Copyright (C) 2011-2013, Free Software Foundation, Inc. *
* * * *
* GNAT is free software; you can redistribute it and/or modify it under * * GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- * * terms of the GNU General Public License as published by the Free Soft- *
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* * * *
* C Implementation File * * C Implementation File *
* * * *
* Copyright (C) 2008-2012, AdaCore * * Copyright (C) 2008-2013, AdaCore *
* * * *
* GNAT is free software; you can redistribute it and/or modify it under * * GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- * * terms of the GNU General Public License as published by the Free Soft- *
......
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