[PATCH] Fix invalid DW_AT_{lower,upper}_bound attributes (PR debug/43237)
Jakub Jelinek
jakub@redhat.com
Tue Mar 2 23:31:00 GMT 2010
Hi!
I've noticed
readelf -wo gcc/cc1 >/dev/null
readelf: Warning: There is a hole [0xd48fba - 0xd48fea] in .debug_loc section.
readelf: Warning: There is a hole [0xd49311 - 0xd49381] in .debug_loc section.
errors today. The problem is that if the artificial VAR_DECL for the
VLA bound doesn't have always the same location expression (or isn't valid
through the whole lifetime) we attempt to emit DW_AT_upper_bound as
loclistptr, which is not valid for this attribute. DW_AT_upper_bound can be
a constant, or an expression block (that is when the list is single
element), or a reference. The following patch fixes it by emitting a
reference to an artificial DW_TAG_variable with the loclistptr in
DW_AT_location.
Bootstrapped/regtested on x86_64-linux and i686-linux, the readelf -wo
warnings are gone. Ok for trunk?
2010-03-02 Jakub Jelinek <jakub@redhat.com>
PR debug/43237
* dwarf2out.c (add_bound_info): If a decl bound doesn't have decl_die,
fallthrough to default handling, just with want_address 0 instead of 2.
For single element lists, add_AT_loc directly, otherwise create an
artificial variable DIE and stick location list to it.
* gcc.dg/debug/dwarf2/pr43237.c: New test.
--- gcc/dwarf2out.c.jj 2010-02-19 09:23:10.000000000 +0100
+++ gcc/dwarf2out.c 2010-03-02 20:02:38.000000000 +0100
@@ -16275,6 +16275,8 @@ add_comp_dir_attribute (dw_die_ref die)
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:
@@ -16324,7 +16326,6 @@ add_bound_info (dw_die_ref subrange_die,
case RESULT_DECL:
{
dw_die_ref decl_die = lookup_decl_die (bound);
- dw_loc_list_ref loc;
/* ??? Can this happen, or should the variable have been bound
first? Probably it can, since I imagine that we try to create
@@ -16332,14 +16333,13 @@ add_bound_info (dw_die_ref subrange_die,
the list, and won't have created a forward reference to a
later parameter. */
if (decl_die != NULL)
- add_AT_die_ref (subrange_die, bound_attr, decl_die);
- else
{
- loc = loc_list_from_tree (bound, 0);
- add_AT_location_description (subrange_die, bound_attr, loc);
+ add_AT_die_ref (subrange_die, bound_attr, decl_die);
+ break;
}
- break;
+ want_address = 0;
}
+ /* FALLTHRU */
default:
{
@@ -16349,10 +16349,16 @@ 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, 2);
+ list = loc_list_from_tree (bound, want_address);
if (list == NULL)
break;
+ if (single_element_loc_list_p (list))
+ {
+ add_AT_loc (subrange_die, bound_attr, list->expr);
+ break;
+ }
+
if (current_function_decl == 0)
ctx = comp_unit_die;
else
@@ -16361,11 +16367,7 @@ add_bound_info (dw_die_ref subrange_die,
decl_die = new_die (DW_TAG_variable, ctx, bound);
add_AT_flag (decl_die, DW_AT_artificial, 1);
add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
- if (list->dw_loc_next)
- add_AT_loc_list (decl_die, DW_AT_location, list);
- else
- add_AT_loc (decl_die, DW_AT_location, list->expr);
-
+ add_AT_location_description (decl_die, DW_AT_location, list);
add_AT_die_ref (subrange_die, bound_attr, decl_die);
break;
}
--- gcc/testsuite/gcc.dg/debug/dwarf2/pr43237.c.jj 2010-03-02 21:51:41.000000000 +0100
+++ gcc/testsuite/gcc.dg/debug/dwarf2/pr43237.c 2010-03-02 21:52:37.000000000 +0100
@@ -0,0 +1,31 @@
+/* PR debug/43237 */
+/* { dg-do compile } */
+/* { dg-options "-g -O2 -dA -fno-merge-debug-strings" } */
+
+struct S
+{
+ int *a;
+ int b;
+ int **c;
+ int d;
+};
+
+void foo (struct S *);
+void bar (struct S *);
+
+int
+baz (void)
+{
+ struct S s;
+ foo (&s);
+ {
+ int a[s.b];
+ int *c[s.d];
+ s.a = a;
+ s.c = c;
+ bar (&s);
+ }
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "LLST\[^\\r\\n\]*DW_AT_upper_bound" } } */
Jakub
More information about the Gcc-patches
mailing list