aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-06-15 11:56:33 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-06-15 11:56:33 +0200
commitba45cfc48b59e577302d5d08f98a866344fbe850 (patch)
tree8ef405eabe93d961cd8fbfbd078c16a00c8fe86b /gcc
parent6fc5966fe8f81fb8b89f4268d52f488e81c257aa (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/dwarf2out.c39
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)