diff options
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 27 |
2 files changed, 24 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4336abd..630a8d0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2011-07-28 Jakub Jelinek <jakub@redhat.com> + * dwarf2out.c (resolve_addr): For -gdwarf-2 don't + optimize DW_AT_data_member_location containing just + DW_OP_plus_uconst. + PR debug/49871 * dwarf2out.c (size_of_die, value_format, output_die): Use DW_FORM_udata instead of DW_FORM_data[48] for diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 806c0d75c..a38bcf8 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -21809,13 +21809,26 @@ resolve_addr (dw_die_ref die) } break; case dw_val_class_loc: - if (!resolve_addr_in_expr (AT_loc (a))) - { - remove_AT (die, a->dw_attr); - ix--; - } - else - mark_base_types (AT_loc (a)); + { + dw_loc_descr_ref l = AT_loc (a); + /* For -gdwarf-2 don't attempt to optimize + DW_AT_data_member_location containing + DW_OP_plus_uconst - older consumers might + rely on it being that op instead of a more complex, + but shorter, location description. */ + if ((dwarf_version > 2 + || a->dw_attr != DW_AT_data_member_location + || l == NULL + || l->dw_loc_opc != DW_OP_plus_uconst + || l->dw_loc_next != NULL) + && !resolve_addr_in_expr (l)) + { + remove_AT (die, a->dw_attr); + ix--; + } + else + mark_base_types (l); + } break; case dw_val_class_addr: if (a->dw_attr == DW_AT_const_value |