From: Jakub Jelinek Date: Wed, 15 Jun 2011 09:56:33 +0000 (+0200) Subject: re PR debug/49382 (-O2 -g: DW_AT_location at the very first PC is already modified) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ba45cfc48b59e577302d5d08f98a866344fbe850;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c055b3d1bf..a4c589fa310 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2011-06-15 Jakub Jelinek + + 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 PR target/49349 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)