aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2009-12-14 16:55:52 +0000
committerJakub Jelinek <jakub@gcc.gnu.org>2009-12-14 17:55:52 +0100
commit2a7d7a8dd74f476fe40052743a81a2c965e71154 (patch)
treede6bb0abac27b0afbf18fa93b34541be17a75439 /gcc
parent23198957a2176cf80b4b33e17f77ab5e5dea4bfe (diff)
downloadgcc-2a7d7a8dd74f476fe40052743a81a2c965e71154.zip
gcc-2a7d7a8dd74f476fe40052743a81a2c965e71154.tar.gz
gcc-2a7d7a8dd74f476fe40052743a81a2c965e71154.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/dwarf2out.c43
2 files changed, 39 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b1094a8..94f46c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,10 @@
2009-12-14 Alexandre Oliva <aoliva@redhat.com>
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.
(new_loc_list): Drop gensym arg. Move generation of ll_symbol...
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 971b191..b3aa5a5 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: