summaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2011-06-15 09:56:33 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2011-06-15 09:56:33 +0000
commitaaec0525605f59f6cafd5cc087716a1cb59ae863 (patch)
tree8ef405eabe93d961cd8fbfbd078c16a00c8fe86b /gcc/dwarf2out.c
parentf550c9b3f562ac78c95ef1c93da6e929a71e1b9b (diff)
downloadgcc-aaec0525605f59f6cafd5cc087716a1cb59ae863.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@175076 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 9ea8a299b1b..71ba002cb85 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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)