re PR target/41473 (dsymutil "Assertion failed ...")
PR debug/41473 * dwarf2out.c (add_var_loc_to_decl): Don't drop initial empty locations. (new_loc_list): Drop gensym arg. Move generation of ll_symbol... (gen_llsym): ... here. New function. (add_loc_descr_to_loc_list): Removed. (loc_descriptor): Infer mode from CONST_DOUBLEs and CONST_VECTORs. (single_element_loc_list): Removed. (dw_loc_list): Don't create entries without a location. Don't special-case the first node of the list, only single nodes. (single_element_loc_list_p): Simplify. (loc_list_from_tree): Don't use DECL_RTL if loc_list is nonempty. (add_location_or_const_value_attribute): Test var loc for NULL. (convert_cfa_to_fb_loc_list): Adjust calls to new new_loc_list, call gen_llsym if needed. From-SVN: r155221
This commit is contained in:
parent
20cdc2be22
commit
23198957a2
|
@ -1,3 +1,21 @@
|
|||
2009-12-14 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
PR debug/41473
|
||||
* dwarf2out.c (add_var_loc_to_decl): Don't drop initial empty
|
||||
locations.
|
||||
(new_loc_list): Drop gensym arg. Move generation of ll_symbol...
|
||||
(gen_llsym): ... here. New function.
|
||||
(add_loc_descr_to_loc_list): Removed.
|
||||
(loc_descriptor): Infer mode from CONST_DOUBLEs and CONST_VECTORs.
|
||||
(single_element_loc_list): Removed.
|
||||
(dw_loc_list): Don't create entries without a location. Don't
|
||||
special-case the first node of the list, only single nodes.
|
||||
(single_element_loc_list_p): Simplify.
|
||||
(loc_list_from_tree): Don't use DECL_RTL if loc_list is nonempty.
|
||||
(add_location_or_const_value_attribute): Test var loc for NULL.
|
||||
(convert_cfa_to_fb_loc_list): Adjust calls to new new_loc_list,
|
||||
call gen_llsym if needed.
|
||||
|
||||
2009-12-14 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* cgraph.h (cgraph_set_nothrow_flag, cgraph_set_readonly_flag,
|
||||
|
|
160
gcc/dwarf2out.c
160
gcc/dwarf2out.c
|
@ -6177,10 +6177,7 @@ static void gen_generic_params_dies (tree);
|
|||
static void splice_child_die (dw_die_ref, dw_die_ref);
|
||||
static int file_info_cmp (const void *, const void *);
|
||||
static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *,
|
||||
const char *, const char *, unsigned);
|
||||
static void add_loc_descr_to_loc_list (dw_loc_list_ref *, dw_loc_descr_ref,
|
||||
const char *, const char *,
|
||||
const char *);
|
||||
const char *, const char *);
|
||||
static void output_loc_list (dw_loc_list_ref);
|
||||
static char *gen_internal_sym (const char *);
|
||||
|
||||
|
@ -7793,8 +7790,7 @@ add_var_loc_to_decl (tree decl, struct var_loc_node *loc)
|
|||
temp->last = loc;
|
||||
}
|
||||
}
|
||||
/* Do not add empty location to the beginning of the list. */
|
||||
else if (NOTE_VAR_LOCATION_LOC (loc->var_loc_note) != NULL_RTX)
|
||||
else
|
||||
{
|
||||
temp->first = loc;
|
||||
temp->last = loc;
|
||||
|
@ -10302,12 +10298,11 @@ output_die_symbol (dw_die_ref die)
|
|||
}
|
||||
|
||||
/* Return a new location list, given the begin and end range, and the
|
||||
expression. gensym tells us whether to generate a new internal symbol for
|
||||
this location list node, which is done for the head of the list only. */
|
||||
expression. */
|
||||
|
||||
static inline dw_loc_list_ref
|
||||
new_loc_list (dw_loc_descr_ref expr, const char *begin, const char *end,
|
||||
const char *section, unsigned int gensym)
|
||||
const char *section)
|
||||
{
|
||||
dw_loc_list_ref retlist = GGC_CNEW (dw_loc_list_node);
|
||||
|
||||
|
@ -10315,27 +10310,18 @@ new_loc_list (dw_loc_descr_ref expr, const char *begin, const char *end,
|
|||
retlist->end = end;
|
||||
retlist->expr = expr;
|
||||
retlist->section = section;
|
||||
if (gensym)
|
||||
retlist->ll_symbol = gen_internal_sym ("LLST");
|
||||
|
||||
return retlist;
|
||||
}
|
||||
|
||||
/* Add a location description expression to a location list. */
|
||||
/* Generate a new internal symbol for this location list node, if it
|
||||
hasn't got one yet. */
|
||||
|
||||
static inline void
|
||||
add_loc_descr_to_loc_list (dw_loc_list_ref *list_head, dw_loc_descr_ref descr,
|
||||
const char *begin, const char *end,
|
||||
const char *section)
|
||||
gen_llsym (dw_loc_list_ref list)
|
||||
{
|
||||
dw_loc_list_ref *d;
|
||||
|
||||
/* Find the end of the chain. */
|
||||
for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next)
|
||||
;
|
||||
|
||||
/* Add a new location list node to the list. */
|
||||
*d = new_loc_list (descr, begin, end, section, 0);
|
||||
gcc_assert (!list->ll_symbol);
|
||||
list->ll_symbol = gen_internal_sym ("LLST");
|
||||
}
|
||||
|
||||
/* Output the location list given to us. */
|
||||
|
@ -13653,15 +13639,17 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
|
|||
break;
|
||||
|
||||
case CONST_DOUBLE:
|
||||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (rtl);
|
||||
|
||||
if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
|
||||
{
|
||||
gcc_assert (mode == GET_MODE (rtl) || VOIDmode == GET_MODE (rtl));
|
||||
|
||||
/* Note that a CONST_DOUBLE rtx could represent either an integer
|
||||
or a floating-point constant. A CONST_DOUBLE is used whenever
|
||||
the constant requires more than one word in order to be
|
||||
adequately represented. We output CONST_DOUBLEs as blocks. */
|
||||
if (GET_MODE (rtl) != VOIDmode)
|
||||
mode = GET_MODE (rtl);
|
||||
|
||||
loc_result = new_loc_descr (DW_OP_implicit_value,
|
||||
GET_MODE_SIZE (mode), 0);
|
||||
if (SCALAR_FLOAT_MODE_P (mode))
|
||||
|
@ -13687,6 +13675,9 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
|
|||
break;
|
||||
|
||||
case CONST_VECTOR:
|
||||
if (mode == VOIDmode)
|
||||
mode = GET_MODE (rtl);
|
||||
|
||||
if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
|
||||
{
|
||||
unsigned int elt_size = GET_MODE_UNIT_SIZE (GET_MODE (rtl));
|
||||
|
@ -13695,7 +13686,7 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
|
|||
unsigned int i;
|
||||
unsigned char *p;
|
||||
|
||||
mode = GET_MODE (rtl);
|
||||
gcc_assert (mode == GET_MODE (rtl) || VOIDmode == GET_MODE (rtl));
|
||||
switch (GET_MODE_CLASS (mode))
|
||||
{
|
||||
case MODE_VECTOR_INT:
|
||||
|
@ -13842,14 +13833,6 @@ decl_by_reference_p (tree decl)
|
|||
&& DECL_BY_REFERENCE (decl));
|
||||
}
|
||||
|
||||
/* Return single element location list containing loc descr REF. */
|
||||
|
||||
static dw_loc_list_ref
|
||||
single_element_loc_list (dw_loc_descr_ref ref)
|
||||
{
|
||||
return new_loc_list (ref, NULL, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
/* Helper function for dw_loc_list. Compute proper Dwarf location descriptor
|
||||
for VARLOC. */
|
||||
|
||||
|
@ -13931,20 +13914,21 @@ dw_loc_list_1 (tree loc, rtx varloc, int want_address,
|
|||
return descr;
|
||||
}
|
||||
|
||||
/* Return dwarf representation of location list representing for
|
||||
LOC_LIST of DECL. WANT_ADDRESS has the same meaning as in
|
||||
loc_list_from_tree function. */
|
||||
/* Return the dwarf representation of the location list LOC_LIST of
|
||||
DECL. WANT_ADDRESS has the same meaning as in loc_list_from_tree
|
||||
function. */
|
||||
|
||||
static dw_loc_list_ref
|
||||
dw_loc_list (var_loc_list * loc_list, tree decl, int want_address)
|
||||
dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
|
||||
{
|
||||
const char *endname, *secname;
|
||||
dw_loc_list_ref list;
|
||||
rtx varloc;
|
||||
enum var_init_status initialized;
|
||||
struct var_loc_node *node;
|
||||
dw_loc_descr_ref descr;
|
||||
char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
|
||||
dw_loc_list_ref list = NULL;
|
||||
dw_loc_list_ref *listp = &list;
|
||||
|
||||
/* Now that we know what section we are using for a base,
|
||||
actually construct the list of locations.
|
||||
|
@ -13957,26 +13941,9 @@ dw_loc_list (var_loc_list * loc_list, tree decl, int want_address)
|
|||
This means we have to special case the last node, and generate
|
||||
a range of [last location start, end of function label]. */
|
||||
|
||||
node = loc_list->first;
|
||||
secname = secname_for_decl (decl);
|
||||
|
||||
if (NOTE_VAR_LOCATION_LOC (node->var_loc_note))
|
||||
initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
|
||||
else
|
||||
initialized = VAR_INIT_STATUS_INITIALIZED;
|
||||
varloc = NOTE_VAR_LOCATION (node->var_loc_note);
|
||||
descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
|
||||
|
||||
if (loc_list && loc_list->first != loc_list->last)
|
||||
list = new_loc_list (descr, node->label, node->next->label, secname, 1);
|
||||
else
|
||||
return single_element_loc_list (descr);
|
||||
node = node->next;
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
for (; node->next; node = node->next)
|
||||
for (node = loc_list->first; node->next; node = node->next)
|
||||
if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
|
||||
{
|
||||
/* The variable has a location between NODE->LABEL and
|
||||
|
@ -13984,28 +13951,46 @@ dw_loc_list (var_loc_list * loc_list, tree decl, int want_address)
|
|||
initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
|
||||
varloc = NOTE_VAR_LOCATION (node->var_loc_note);
|
||||
descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
|
||||
add_loc_descr_to_loc_list (&list, descr,
|
||||
node->label, node->next->label, secname);
|
||||
if (descr)
|
||||
{
|
||||
*listp = new_loc_list (descr, node->label, node->next->label,
|
||||
secname);
|
||||
listp = &(*listp)->dw_loc_next;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the variable has a location at the last label
|
||||
it keeps its location until the end of function. */
|
||||
if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
|
||||
{
|
||||
if (!current_function_decl)
|
||||
endname = text_end_label;
|
||||
else
|
||||
{
|
||||
ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
|
||||
current_function_funcdef_no);
|
||||
endname = ggc_strdup (label_id);
|
||||
}
|
||||
|
||||
initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
|
||||
varloc = NOTE_VAR_LOCATION (node->var_loc_note);
|
||||
descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
|
||||
add_loc_descr_to_loc_list (&list, descr, node->label, endname, secname);
|
||||
if (descr)
|
||||
{
|
||||
if (!current_function_decl)
|
||||
endname = text_end_label;
|
||||
else
|
||||
{
|
||||
ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
|
||||
current_function_funcdef_no);
|
||||
endname = ggc_strdup (label_id);
|
||||
}
|
||||
|
||||
*listp = new_loc_list (descr, node->label, endname, secname);
|
||||
listp = &(*listp)->dw_loc_next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to avoid the overhead of a location list emitting a location
|
||||
expression instead, but only if we didn't have more than one
|
||||
location entry in the first place. If some entries were not
|
||||
representable, we don't want to pretend a single entry that was
|
||||
applies to the entire scope in which the variable is
|
||||
available. */
|
||||
if (list && loc_list->first->next)
|
||||
gen_llsym (list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -14015,7 +14000,8 @@ dw_loc_list (var_loc_list * loc_list, tree decl, int want_address)
|
|||
static bool
|
||||
single_element_loc_list_p (dw_loc_list_ref list)
|
||||
{
|
||||
return (!list->dw_loc_next && !list->begin && !list->end);
|
||||
gcc_assert (!list->dw_loc_next || list->ll_symbol);
|
||||
return !list->ll_symbol;
|
||||
}
|
||||
|
||||
/* To each location in list LIST add loc descr REF. */
|
||||
|
@ -14315,9 +14301,9 @@ loc_list_from_tree (tree loc, int want_address)
|
|||
rtx rtl;
|
||||
var_loc_list *loc_list = lookup_decl_loc (loc);
|
||||
|
||||
if (loc_list && loc_list->first
|
||||
&& (list_ret = dw_loc_list (loc_list, loc, want_address)))
|
||||
if (loc_list && loc_list->first)
|
||||
{
|
||||
list_ret = dw_loc_list (loc_list, loc, want_address);
|
||||
have_address = want_address != 0;
|
||||
break;
|
||||
}
|
||||
|
@ -14728,7 +14714,7 @@ loc_list_from_tree (tree loc, int want_address)
|
|||
add_loc_descr_to_each (list_ret, new_loc_descr (op, size, 0));
|
||||
}
|
||||
if (ret)
|
||||
list_ret = single_element_loc_list (ret);
|
||||
list_ret = new_loc_list (ret, NULL, NULL, NULL);
|
||||
|
||||
return list_ret;
|
||||
}
|
||||
|
@ -15722,15 +15708,18 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
|
|||
a constant value. That way we are better to use add_const_value_attribute
|
||||
rather than expanding constant value equivalent. */
|
||||
loc_list = lookup_decl_loc (decl);
|
||||
if (loc_list && loc_list->first && loc_list->first == loc_list->last)
|
||||
if (loc_list
|
||||
&& loc_list->first
|
||||
&& loc_list->first == loc_list->last
|
||||
&& NOTE_VAR_LOCATION (loc_list->first->var_loc_note)
|
||||
&& NOTE_VAR_LOCATION_LOC (loc_list->first->var_loc_note))
|
||||
{
|
||||
struct var_loc_node *node;
|
||||
|
||||
node = loc_list->first;
|
||||
rtl = NOTE_VAR_LOCATION (node->var_loc_note);
|
||||
if (GET_CODE (rtl) == VAR_LOCATION
|
||||
&& GET_CODE (XEXP (rtl, 1)) != PARALLEL)
|
||||
rtl = XEXP (XEXP (rtl, 1), 0);
|
||||
rtl = NOTE_VAR_LOCATION_LOC (node->var_loc_note);
|
||||
if (GET_CODE (rtl) != PARALLEL)
|
||||
rtl = XEXP (rtl, 0);
|
||||
if ((CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING)
|
||||
&& add_const_value_attribute (die, rtl))
|
||||
return true;
|
||||
|
@ -16017,8 +16006,7 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
|
|||
if (!cfa_equal_p (&last_cfa, &next_cfa))
|
||||
{
|
||||
*list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
|
||||
start_label, last_label, section,
|
||||
list == NULL);
|
||||
start_label, last_label, section);
|
||||
|
||||
list_tail = &(*list_tail)->dw_loc_next;
|
||||
last_cfa = next_cfa;
|
||||
|
@ -16039,14 +16027,16 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
|
|||
if (!cfa_equal_p (&last_cfa, &next_cfa))
|
||||
{
|
||||
*list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
|
||||
start_label, last_label, section,
|
||||
list == NULL);
|
||||
start_label, last_label, section);
|
||||
list_tail = &(*list_tail)->dw_loc_next;
|
||||
start_label = last_label;
|
||||
}
|
||||
|
||||
*list_tail = new_loc_list (build_cfa_loc (&next_cfa, offset),
|
||||
start_label, fde->dw_fde_end, section,
|
||||
list == NULL);
|
||||
start_label, fde->dw_fde_end, section);
|
||||
|
||||
if (list && list->dw_loc_next)
|
||||
gen_llsym (list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue