+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
/* 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);
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;
}
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;
{
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)
{
}
*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)