[PATCH] Fix DW_AT_{lower,upper}_bound for VLAs (PR debug/43762)
Richard Guenther
rguenther@suse.de
Fri Apr 16 14:31:00 GMT 2010
On Fri, 16 Apr 2010, Jakub Jelinek wrote:
> Hi!
>
> If add_bound_info is called with an artificial VAR_DECL represented with
> a location list with more than one range, GCC currently emits incorrect
> DW_AT_location for the artificial DIE that is referenced (doesn't contain
> DW_OP_stack_value at the end of the ranges). On the other side, if
> bound happened to be some arbitrary expressions and a single location
> description could be useful for it, we'd not emit DW_OP_deref at the end
> that needs to be there.
>
> The problem is that unlike say DW_AT_location attribute whose argument is
> a DWARF location description or location list pointer (list of ranges
> with location description), DW_AT_upper_bound etc. can be a constant,
> reference (then it references some DIE with its DW_AT_location and thus
> again location description or location list pointer) or DWARF expression.
> The difference between the two is that DWARF expression computes some value
> on the stack and in DW_AT_upper_bound case the value from TOS is the bound.
> DWARF location description is either some DW_OP_reg{N,x}, or DWARF
> expression (then it is an address of a memory and the value is what the
> memory contains) or DWARF expression + DW_OP_stack_value (then it is
> that value) or a few other cases.
>
> For add_bound_info this means that it needs to call loc_list_from_tree twice
> (once with 2 for use in DW_AT_location for an artificial DIE, once with 0
> to compute a DWARF expression if there is a chance the latter could be a
> single expression).
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk
> and 4.5?
Testcase?
Otherwise ok for trunk and 4.5 after a while.
Thanks,
Richard.
> 2010-04-16 Jakub Jelinek <jakub@redhat.com>
>
> PR debug/43762
> * dwarf2out.c (add_bound_info): Always call loc_list_from_tree
> with want_address 2 and in case a single element list might be
> possible, call it again with want_address 0.
>
> --- gcc/dwarf2out.c.jj 2010-04-07 13:39:55.000000000 +0200
> +++ gcc/dwarf2out.c 2010-04-16 13:55:16.000000000 +0200
> @@ -16355,8 +16355,6 @@ lower_bound_default (void)
> static void
> add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree bound)
> {
> - int want_address = 2;
> -
> switch (TREE_CODE (bound))
> {
> case ERROR_MARK:
> @@ -16419,7 +16417,6 @@ add_bound_info (dw_die_ref subrange_die,
> add_AT_die_ref (subrange_die, bound_attr, decl_die);
> break;
> }
> - want_address = 0;
> }
> /* FALLTHRU */
>
> @@ -16431,15 +16428,23 @@ add_bound_info (dw_die_ref subrange_die,
> dw_die_ref ctx, decl_die;
> dw_loc_list_ref list;
>
> - list = loc_list_from_tree (bound, want_address);
> - if (list == NULL)
> - break;
> -
> - if (single_element_loc_list_p (list))
> + list = loc_list_from_tree (bound, 2);
> + if (list == NULL || single_element_loc_list_p (list))
> {
> - add_AT_loc (subrange_die, bound_attr, list->expr);
> - break;
> + /* If DW_AT_*bound is not a reference nor constant, it is
> + a DWARF expression rather than location description.
> + For that loc_list_from_tree (bound, 0) is needed.
> + If that fails to give a single element list,
> + fall back to outputting this as a reference anyway. */
> + dw_loc_list_ref list2 = loc_list_from_tree (bound, 0);
> + if (list2 && single_element_loc_list_p (list2))
> + {
> + add_AT_loc (subrange_die, bound_attr, list2->expr);
> + break;
> + }
> }
> + if (list == NULL)
> + break;
>
> if (current_function_decl == 0)
> ctx = comp_unit_die;
>
> Jakub
>
>
--
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex
More information about the Gcc-patches
mailing list