diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-15 09:56:33 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-15 09:56:33 +0000 |
commit | aaec0525605f59f6cafd5cc087716a1cb59ae863 (patch) | |
tree | 8ef405eabe93d961cd8fbfbd078c16a00c8fe86b /gcc/dwarf2out.c | |
parent | f550c9b3f562ac78c95ef1c93da6e929a71e1b9b (diff) | |
download | gcc-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.c | 39 |
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) |