aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Berlin <dberlin@dberlin.org>2005-01-20 20:09:22 +0000
committerDaniel Berlin <dberlin@gcc.gnu.org>2005-01-20 20:09:22 +0000
commit3c46c513c2008d845cf09642aef08b78b1d2f226 (patch)
tree302dada6aafe211b1bea0e17a54e27a3d262111d
parent23ab2e4e18a866eee66c4576b4a7f98c1124cbf4 (diff)
downloadgcc-3c46c513c2008d845cf09642aef08b78b1d2f226.zip
gcc-3c46c513c2008d845cf09642aef08b78b1d2f226.tar.gz
gcc-3c46c513c2008d845cf09642aef08b78b1d2f226.tar.bz2
re PR debug/19124 (gcc generates incorrect dwarf2 debug info)
2005-01-20 Daniel Berlin <dberlin@dberlin.org> Fix PR debug/19124 * dwarf2out.c (concat_loc_descriptor): We don't know we can use fbreg, so we have to assume we can't. (loc_descriptor_from_tree_1): Ditto. (containing_function_has_frame_base): New function. (add_location_or_const_value_attribute): Use it. Also try to generate a frame_base from a single element location list. From-SVN: r93979
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/dwarf2out.c70
2 files changed, 69 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 53d41db..cf511fa 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2005-01-20 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR debug/19124
+ * dwarf2out.c (concat_loc_descriptor): We don't know we can use
+ fbreg, so we have to assume we can't.
+ (loc_descriptor_from_tree_1): Ditto.
+ (containing_function_has_frame_base): New function.
+ (add_location_or_const_value_attribute): Use it.
+ Also try to generate a frame_base from a single element location
+ list.
+
2005-01-20 Kazu Hirata <kazu@cs.umass.edu>
PR tree-optimization/15349
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 76f67a5..6336cf6 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -8714,8 +8714,8 @@ static dw_loc_descr_ref
concat_loc_descriptor (rtx x0, rtx x1)
{
dw_loc_descr_ref cc_loc_result = NULL;
- dw_loc_descr_ref x0_ref = loc_descriptor (x0, true);
- dw_loc_descr_ref x1_ref = loc_descriptor (x1, true);
+ dw_loc_descr_ref x0_ref = loc_descriptor (x0, false);
+ dw_loc_descr_ref x1_ref = loc_descriptor (x1, false);
if (x0_ref == 0 || x1_ref == 0)
return 0;
@@ -8934,7 +8934,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
/* Certain constructs can only be represented at top-level. */
if (want_address == 2)
- return loc_descriptor (rtl, true);
+ return loc_descriptor (rtl, false);
mode = GET_MODE (rtl);
if (MEM_P (rtl))
@@ -8942,7 +8942,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
rtl = XEXP (rtl, 0);
have_address = 1;
}
- ret = mem_loc_descriptor (rtl, mode, true);
+ ret = mem_loc_descriptor (rtl, mode, false);
}
}
break;
@@ -9021,7 +9021,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
return 0;
mode = GET_MODE (rtl);
rtl = XEXP (rtl, 0);
- ret = mem_loc_descriptor (rtl, mode, true);
+ ret = mem_loc_descriptor (rtl, mode, false);
have_address = 1;
break;
}
@@ -9971,6 +9971,29 @@ rtl_for_decl_location (tree decl)
return rtl;
}
+/* Return true if DECL's containing function has a frame base attribute.
+ Return false otherwise. */
+
+static bool
+containing_function_has_frame_base (tree decl)
+{
+ tree declcontext = decl_function_context (decl);
+ dw_die_ref context;
+ dw_attr_ref attr;
+
+ if (!declcontext)
+ return false;
+
+ context = lookup_decl_die (declcontext);
+ if (!context)
+ return false;
+
+ for (attr = context->die_attr; attr; attr = attr->dw_attr_next)
+ if (attr->dw_attr == DW_AT_frame_base)
+ return true;
+ return false;
+}
+
/* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
data attribute for a variable or a parameter. We generate the
DW_AT_const_value attribute only in those cases where the given variable
@@ -9989,12 +10012,15 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
rtx rtl;
dw_loc_descr_ref descr;
var_loc_list *loc_list;
-
+ bool can_use_fb;
+ struct var_loc_node *node;
if (TREE_CODE (decl) == ERROR_MARK)
return;
gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL
|| TREE_CODE (decl) == RESULT_DECL);
+
+ can_use_fb = containing_function_has_frame_base (decl);
/* See if we possibly have multiple locations for this variable. */
loc_list = lookup_decl_loc (decl);
@@ -10007,7 +10033,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
const char *endname;
dw_loc_list_ref list;
rtx varloc;
- struct var_loc_node *node;
+
/* We need to figure out what section we should use as the base
for the address ranges where a given location is valid.
@@ -10046,7 +10072,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
node = loc_list->first;
varloc = NOTE_VAR_LOCATION (node->var_loc_note);
- list = new_loc_list (loc_descriptor (varloc, attr != DW_AT_frame_base),
+ list = new_loc_list (loc_descriptor (varloc, can_use_fb),
node->label, node->next->label, secname, 1);
node = node->next;
@@ -10058,7 +10084,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
varloc = NOTE_VAR_LOCATION (node->var_loc_note);
add_loc_descr_to_loc_list (&list,
loc_descriptor (varloc,
- attr != DW_AT_frame_base),
+ can_use_fb),
node->label, node->next->label, secname);
}
@@ -10079,7 +10105,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
}
add_loc_descr_to_loc_list (&list,
loc_descriptor (varloc,
- attr != DW_AT_frame_base),
+ can_use_fb),
node->label, endname, secname);
}
@@ -10088,16 +10114,36 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
return;
}
+ /* Try to get some constant RTL for this decl, and use that as the value of
+ the location. */
+
rtl = rtl_for_decl_location (decl);
if (rtl && (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING))
{
add_const_value_attribute (die, rtl);
return;
}
-
+
+ /* We couldn't get any rtl, and we had no >1 element location list, so try
+ directly generating the location description from the tree. */
descr = loc_descriptor_from_tree (decl);
if (descr)
- add_AT_location_description (die, attr, descr);
+ {
+ add_AT_location_description (die, attr, descr);
+ return;
+ }
+
+ /* Lastly, if we have tried to generate the location otherwise, and it
+ didn't work out (we wouldn't be here if we did), and we have a one entry
+ location list, try generating a location from that. */
+ if (loc_list && loc_list->first)
+ {
+ node = loc_list->first;
+ descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note),
+ can_use_fb);
+ if (descr)
+ add_AT_location_description (die, attr, descr);
+ }
}
/* If we don't have a copy of this variable in memory for some reason (such