Commit ba45cfc4 by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/49382 (-O2 -g: DW_AT_location at the very first PC is already modified)

	PR debug/49382
	* dwarf2out.c (dw_loc_list_node): Add force field.
	(add_var_loc_to_decl): For PARM_DECL, attempt to keep
	the incoming location in the list, even if it is modified
	before first real insn.
	(output_loc_list): Emit empty ranges with force flag set.
	(dw_loc_list): If first range of a PARM_DECL is empty,
	set force flag.

From-SVN: r175076
parent 6fc5966f
2011-06-15 Jakub Jelinek <jakub@redhat.com>
PR debug/49382
* dwarf2out.c (dw_loc_list_node): Add force field.
(add_var_loc_to_decl): For PARM_DECL, attempt to keep
the incoming location in the list, even if it is modified
before first real insn.
(output_loc_list): Emit empty ranges with force flag set.
(dw_loc_list): If first range of a PARM_DECL is empty,
set force flag.
2011-06-15 Alexander Monakov <amonakov@ispras.ru>
PR target/49349
......
......@@ -4467,6 +4467,9 @@ typedef struct GTY(()) dw_loc_list_struct {
/* True if this list has been replaced by dw_loc_next. */
bool replaced;
bool emitted;
/* True if the range should be emitted even if begin and end
are the same. */
bool force;
} dw_loc_list_node;
static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
......@@ -8621,7 +8624,30 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
else
temp = (var_loc_list *) *slot;
if (temp->last)
/* For PARM_DECLs try to keep around the original incoming value,
even if that means we'll emit a zero-range .debug_loc entry. */
if (temp->last
&& temp->first == temp->last
&& TREE_CODE (decl) == PARM_DECL
&& GET_CODE (temp->first->loc) == NOTE
&& NOTE_VAR_LOCATION_DECL (temp->first->loc) == decl
&& DECL_INCOMING_RTL (decl)
&& NOTE_VAR_LOCATION_LOC (temp->first->loc)
&& GET_CODE (NOTE_VAR_LOCATION_LOC (temp->first->loc))
== GET_CODE (DECL_INCOMING_RTL (decl))
&& prev_real_insn (temp->first->loc) == NULL_RTX
&& (bitsize != -1
|| !rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->first->loc),
NOTE_VAR_LOCATION_LOC (loc_note))
|| (NOTE_VAR_LOCATION_STATUS (temp->first->loc)
!= NOTE_VAR_LOCATION_STATUS (loc_note))))
{
loc = ggc_alloc_cleared_var_loc_node ();
temp->first->next = loc;
temp->last = loc;
loc->loc = construct_piece_list (loc_note, bitpos, bitsize);
}
else if (temp->last)
{
struct var_loc_node *last = temp->last, *unused = NULL;
rtx *piece_loc = NULL, last_loc_note;
......@@ -8667,7 +8693,9 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
}
else
{
gcc_assert (temp->first == temp->last);
gcc_assert (temp->first == temp->last
|| (temp->first->next == temp->last
&& TREE_CODE (decl) == PARM_DECL));
memset (temp->last, '\0', sizeof (*temp->last));
temp->last->loc = construct_piece_list (loc_note, bitpos, bitsize);
return temp->last;
......@@ -11394,7 +11422,7 @@ output_loc_list (dw_loc_list_ref list_head)
{
unsigned long size;
/* Don't output an entry that starts and ends at the same address. */
if (strcmp (curr->begin, curr->end) == 0)
if (strcmp (curr->begin, curr->end) == 0 && !curr->force)
continue;
if (!have_multiple_function_sections)
{
......@@ -16090,6 +16118,11 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
}
*listp = new_loc_list (descr, node->label, endname, secname);
if (TREE_CODE (decl) == PARM_DECL
&& node == loc_list->first
&& GET_CODE (node->loc) == NOTE
&& strcmp (node->label, endname) == 0)
(*listp)->force = true;
listp = &(*listp)->dw_loc_next;
if (range_across_switch)
......
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