From 2a7d7a8dd74f476fe40052743a81a2c965e71154 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Mon, 14 Dec 2009 16:55:52 +0000 Subject: [PATCH] re PR target/41473 (dsymutil "Assertion failed ...") PR debug/41473 * dwarf2out.c (AT_loc_list_ptr): New. (resolve_addr): Remove unresolved attributes and loc_list entries. From-SVN: r155222 --- gcc/ChangeLog | 4 ++++ gcc/dwarf2out.c | 43 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1094a85df1..94f46c87039 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2009-12-14 Alexandre Oliva + PR debug/41473 + * dwarf2out.c (AT_loc_list_ptr): New. + (resolve_addr): Remove unresolved attributes and loc_list entries. + PR debug/41473 * dwarf2out.c (add_var_loc_to_decl): Don't drop initial empty locations. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 971b191b301..b3aa5a5cbc1 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -7211,6 +7211,13 @@ AT_loc_list (dw_attr_ref a) return a->dw_attr_val.v.val_loc_list; } +static inline dw_loc_list_ref * +AT_loc_list_ptr (dw_attr_ref a) +{ + gcc_assert (a && AT_class (a) == dw_val_class_loc_list); + return &a->dw_attr_val.v.val_loc_list; +} + /* Add an address constant attribute value to a DIE. */ static inline void @@ -20968,28 +20975,48 @@ resolve_addr (dw_die_ref die) { dw_die_ref c; dw_attr_ref a; - dw_loc_list_ref curr; + dw_loc_list_ref *curr; unsigned ix; for (ix = 0; VEC_iterate (dw_attr_node, die->die_attr, ix, a); ix++) switch (AT_class (a)) { case dw_val_class_loc_list: - for (curr = AT_loc_list (a); curr != NULL; curr = curr->dw_loc_next) - if (!resolve_addr_in_expr (curr->expr)) - curr->expr = NULL; + curr = AT_loc_list_ptr (a); + while (*curr) + { + if (!resolve_addr_in_expr ((*curr)->expr)) + { + dw_loc_list_ref next = (*curr)->dw_loc_next; + if (next && (*curr)->ll_symbol) + { + gcc_assert (!next->ll_symbol); + next->ll_symbol = (*curr)->ll_symbol; + } + *curr = next; + } + else + curr = &(*curr)->dw_loc_next; + } + if (!AT_loc_list (a)) + { + remove_AT (die, a->dw_attr); + ix--; + } break; case dw_val_class_loc: if (!resolve_addr_in_expr (AT_loc (a))) - a->dw_attr_val.v.val_loc = NULL; + { + remove_AT (die, a->dw_attr); + ix--; + } break; case dw_val_class_addr: if (a->dw_attr == DW_AT_const_value && resolve_one_addr (&a->dw_attr_val.v.val_addr, NULL)) { - a->dw_attr = DW_AT_location; - a->dw_attr_val.val_class = dw_val_class_loc; - a->dw_attr_val.v.val_loc = NULL; + remove_AT (die, a->dw_attr); + ix--; } break; default: