Commit 8b87e0d1 by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/82718 (Bad DWARF5 .debug_loclists generation)

	PR debug/82718
	* dwarf2out.c (dw_loc_list): If crtl->has_bb_partition, temporarily
	set in_cold_section_p to the partition containing loc_list->first.
	When seeing loc_list->last_before_switch node, update secname and
	perform range_across_switch second partition handling only after that.

	* gcc.dg/debug/dwarf2/pr82718-1.c: New test.
	* gcc.dg/debug/dwarf2/pr82718-2.c: New test.

From-SVN: r254989
parent 83087d65
2017-11-21 Jakub Jelinek <jakub@redhat.com> 2017-11-21 Jakub Jelinek <jakub@redhat.com>
PR debug/82718
* dwarf2out.c (dw_loc_list): If crtl->has_bb_partition, temporarily
set in_cold_section_p to the partition containing loc_list->first.
When seeing loc_list->last_before_switch node, update secname and
perform range_across_switch second partition handling only after that.
PR debug/82933 PR debug/82933
* run-rtl-passes.c: Include debug.h. * run-rtl-passes.c: Include debug.h.
(run_rtl_passes): Call debug_hooks->assembly_start. (run_rtl_passes): Call debug_hooks->assembly_start.
...@@ -16366,92 +16366,111 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) ...@@ -16366,92 +16366,111 @@ 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 This means we have to special case the last node, and generate
a range of [last location start, end of function label]. */ a range of [last location start, end of function label]. */
secname = secname_for_decl (decl); if (cfun && crtl->has_bb_partition)
{
bool save_in_cold_section_p = in_cold_section_p;
in_cold_section_p = first_function_block_is_cold;
if (loc_list->last_before_switch == NULL)
in_cold_section_p = !in_cold_section_p;
secname = secname_for_decl (decl);
in_cold_section_p = save_in_cold_section_p;
}
else
secname = secname_for_decl (decl);
for (node = loc_list->first; node; node = node->next) for (node = loc_list->first; node; node = node->next)
if (GET_CODE (node->loc) == EXPR_LIST {
|| NOTE_VAR_LOCATION_LOC (node->loc) != NULL_RTX) bool range_across_switch = false;
{ if (GET_CODE (node->loc) == EXPR_LIST
if (GET_CODE (node->loc) == EXPR_LIST) || NOTE_VAR_LOCATION_LOC (node->loc) != NULL_RTX)
{ {
/* This requires DW_OP_{,bit_}piece, which is not usable if (GET_CODE (node->loc) == EXPR_LIST)
inside DWARF expressions. */ {
if (want_address != 2) descr = NULL;
continue; /* This requires DW_OP_{,bit_}piece, which is not usable
descr = dw_sra_loc_expr (decl, node->loc); inside DWARF expressions. */
if (descr == NULL) if (want_address == 2)
continue; descr = dw_sra_loc_expr (decl, node->loc);
} }
else else
{ {
initialized = NOTE_VAR_LOCATION_STATUS (node->loc); initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
varloc = NOTE_VAR_LOCATION (node->loc); varloc = NOTE_VAR_LOCATION (node->loc);
descr = dw_loc_list_1 (decl, varloc, want_address, initialized); descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
} }
if (descr) if (descr)
{ {
bool range_across_switch = false; /* If section switch happens in between node->label
/* If section switch happens in between node->label and node->next->label (or end of function) and
and node->next->label (or end of function) and we can't emit it as a single entry list,
we can't emit it as a single entry list, emit two ranges, first one ending at the end
emit two ranges, first one ending at the end of first partition and second one starting at the
of first partition and second one starting at the beginning of second partition. */
beginning of second partition. */ if (node == loc_list->last_before_switch
if (node == loc_list->last_before_switch && (node != loc_list->first || loc_list->first->next)
&& (node != loc_list->first || loc_list->first->next) && current_function_decl)
&& current_function_decl) {
{ endname = cfun->fde->dw_fde_end;
endname = cfun->fde->dw_fde_end; range_across_switch = true;
range_across_switch = true; }
} /* The variable has a location between NODE->LABEL and
/* The variable has a location between NODE->LABEL and NODE->NEXT->LABEL. */
NODE->NEXT->LABEL. */ else if (node->next)
else if (node->next) endname = node->next->label;
endname = node->next->label; /* If the variable has a location at the last label
/* If the variable has a location at the last label it keeps its location until the end of function. */
it keeps its location until the end of function. */ else if (!current_function_decl)
else if (!current_function_decl) endname = text_end_label;
endname = text_end_label; else
else {
{ ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL, current_function_funcdef_no);
current_function_funcdef_no); endname = ggc_strdup (label_id);
endname = ggc_strdup (label_id); }
}
*listp = new_loc_list (descr, node->label, endname, secname); *listp = new_loc_list (descr, node->label, endname, secname);
if (TREE_CODE (decl) == PARM_DECL if (TREE_CODE (decl) == PARM_DECL
&& node == loc_list->first && node == loc_list->first
&& NOTE_P (node->loc) && NOTE_P (node->loc)
&& strcmp (node->label, endname) == 0) && strcmp (node->label, endname) == 0)
(*listp)->force = true; (*listp)->force = true;
listp = &(*listp)->dw_loc_next; listp = &(*listp)->dw_loc_next;
}
}
if (range_across_switch) if (cfun
{ && crtl->has_bb_partition
if (GET_CODE (node->loc) == EXPR_LIST) && node == loc_list->last_before_switch)
descr = dw_sra_loc_expr (decl, node->loc); {
else bool save_in_cold_section_p = in_cold_section_p;
{ in_cold_section_p = !first_function_block_is_cold;
initialized = NOTE_VAR_LOCATION_STATUS (node->loc); secname = secname_for_decl (decl);
varloc = NOTE_VAR_LOCATION (node->loc); in_cold_section_p = save_in_cold_section_p;
descr = dw_loc_list_1 (decl, varloc, want_address, }
initialized);
} if (range_across_switch)
gcc_assert (descr); {
/* The variable has a location between NODE->LABEL and if (GET_CODE (node->loc) == EXPR_LIST)
NODE->NEXT->LABEL. */ descr = dw_sra_loc_expr (decl, node->loc);
if (node->next) else
endname = node->next->label; {
else initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
endname = cfun->fde->dw_fde_second_end; varloc = NOTE_VAR_LOCATION (node->loc);
*listp = new_loc_list (descr, descr = dw_loc_list_1 (decl, varloc, want_address,
cfun->fde->dw_fde_second_begin, initialized);
endname, secname); }
listp = &(*listp)->dw_loc_next; gcc_assert (descr);
} /* The variable has a location between NODE->LABEL and
} NODE->NEXT->LABEL. */
} if (node->next)
endname = node->next->label;
else
endname = cfun->fde->dw_fde_second_end;
*listp = new_loc_list (descr, cfun->fde->dw_fde_second_begin,
endname, secname);
listp = &(*listp)->dw_loc_next;
}
}
/* Try to avoid the overhead of a location list emitting a location /* Try to avoid the overhead of a location list emitting a location
expression instead, but only if we didn't have more than one expression instead, but only if we didn't have more than one
......
2017-11-21 Jakub Jelinek <jakub@redhat.com> 2017-11-21 Jakub Jelinek <jakub@redhat.com>
PR debug/82718
* gcc.dg/debug/dwarf2/pr82718-1.c: New test.
* gcc.dg/debug/dwarf2/pr82718-2.c: New test.
PR debug/82933 PR debug/82933
* gcc.dg/rtl/x86_64/pr82933.c: New test. * gcc.dg/rtl/x86_64/pr82933.c: New test.
......
/* PR debug/82718 */
/* { dg-do assemble } */
/* { dg-options "-O2 -gdwarf-5" } */
extern int e;
extern long foo (int, void *, unsigned long, unsigned long);
struct S
{
int f;
unsigned long t, s;
};
static inline long
bv (int x, void *y, unsigned long z, unsigned long w)
{
long a = 0;
do
{
long g;
do
g = (long int) (foo (x, y + a, z - a, w + a));
while (g == -1L && e == 9959);
if (g <= 0)
return g < 0 ? g : a;
a += g;
}
while ((unsigned long) a < z);
return a;
}
const char *
baz (struct S *x)
{
unsigned long h = 8;
char *j = 0;
unsigned long z = x->f;
if (__builtin_expect (!!((unsigned long) bv (x->f, j, z, x->t + h + 10) != z), 0))
return 0;
x->s = z;
return j;
}
/* PR debug/82718 */
/* { dg-do assemble } */
/* { dg-options "-O2 -gdwarf-5" } */
extern int bar (void);
int
foo (int x)
{
if (bar ())
__builtin_abort ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment