[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