diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-06-15 11:56:33 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-06-15 11:56:33 +0200 |
commit | ba45cfc48b59e577302d5d08f98a866344fbe850 (patch) | |
tree | 8ef405eabe93d961cd8fbfbd078c16a00c8fe86b /gcc | |
parent | 6fc5966fe8f81fb8b89f4268d52f488e81c257aa (diff) | |
download | gcc-ba45cfc48b59e577302d5d08f98a866344fbe850.zip gcc-ba45cfc48b59e577302d5d08f98a866344fbe850.tar.gz gcc-ba45cfc48b59e577302d5d08f98a866344fbe850.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 39 |
2 files changed, 47 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c055b3..a4c589f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +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 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 9ea8a29..71ba002 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) |