Commit f980dfdb by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/56154 (Bad .debug_loc generated for some code)

	PR debug/56154
	* dwarf2out.c (dwarf2_debug_hooks): Set end_function hook to
	dwarf2out_end_function.
	(in_first_function_p, maybe_at_text_label_p,
	first_loclabel_num_not_at_text_label): New variables.
	(dwarf2out_var_location): In the first function find out
	lowest loclabel_num N where .LVLN is known not to be equal
	to .Ltext0.
	(find_empty_loc_ranges_at_text_label, dwarf2out_end_function): New
	functions.

	* gcc.dg/guality/pr56154-1.c: New test.
	* gcc.dg/guality/pr56154-2.c: New test.
	* gcc.dg/guality/pr56154-3.c: New test.
	* gcc.dg/guality/pr56154-4.c: New test.
	* gcc.dg/guality/pr56154-aux.c: New file.

From-SVN: r195850
parent fcf0430b
2013-02-07 Jakub Jelinek <jakub@redhat.com>
PR debug/56154
* dwarf2out.c (dwarf2_debug_hooks): Set end_function hook to
dwarf2out_end_function.
(in_first_function_p, maybe_at_text_label_p,
first_loclabel_num_not_at_text_label): New variables.
(dwarf2out_var_location): In the first function find out
lowest loclabel_num N where .LVLN is known not to be equal
to .Ltext0.
(find_empty_loc_ranges_at_text_label, dwarf2out_end_function): New
functions.
2013-02-07 Eric Botcazou <ebotcazou@adacore.com> 2013-02-07 Eric Botcazou <ebotcazou@adacore.com>
PR rtl-optimization/56178 PR rtl-optimization/56178
......
...@@ -2351,6 +2351,7 @@ static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree, ...@@ -2351,6 +2351,7 @@ static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree,
static void dwarf2out_abstract_function (tree); static void dwarf2out_abstract_function (tree);
static void dwarf2out_var_location (rtx); static void dwarf2out_var_location (rtx);
static void dwarf2out_begin_function (tree); static void dwarf2out_begin_function (tree);
static void dwarf2out_end_function (unsigned int);
static void dwarf2out_set_name (tree, tree); static void dwarf2out_set_name (tree, tree);
/* The debug hooks structure. */ /* The debug hooks structure. */
...@@ -2378,7 +2379,7 @@ const struct gcc_debug_hooks dwarf2_debug_hooks = ...@@ -2378,7 +2379,7 @@ const struct gcc_debug_hooks dwarf2_debug_hooks =
#endif #endif
dwarf2out_end_epilogue, dwarf2out_end_epilogue,
dwarf2out_begin_function, dwarf2out_begin_function,
debug_nothing_int, /* end_function */ dwarf2out_end_function, /* end_function */
dwarf2out_function_decl, /* function_decl */ dwarf2out_function_decl, /* function_decl */
dwarf2out_global_decl, dwarf2out_global_decl,
dwarf2out_type_decl, /* type_decl */ dwarf2out_type_decl, /* type_decl */
...@@ -20627,6 +20628,14 @@ dwarf2out_set_name (tree decl, tree name) ...@@ -20627,6 +20628,14 @@ dwarf2out_set_name (tree decl, tree name)
add_name_attribute (die, dname); add_name_attribute (die, dname);
} }
/* True if before or during processing of the first function being emitted. */
static bool in_first_function_p = true;
/* True if loc_note during dwarf2out_var_location call might still be
before first real instruction at address equal to .Ltext0. */
static bool maybe_at_text_label_p = true;
/* One above highest N where .LVLN label might be equal to .Ltext0 label. */
static unsigned int first_loclabel_num_not_at_text_label;
/* Called by the final INSN scan whenever we see a var location. We /* Called by the final INSN scan whenever we see a var location. We
use it to drop labels in the right places, and throw the location in use it to drop labels in the right places, and throw the location in
our lookup table. */ our lookup table. */
...@@ -20734,6 +20743,45 @@ dwarf2out_var_location (rtx loc_note) ...@@ -20734,6 +20743,45 @@ dwarf2out_var_location (rtx loc_note)
ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LVL", loclabel_num); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LVL", loclabel_num);
loclabel_num++; loclabel_num++;
last_label = ggc_strdup (loclabel); last_label = ggc_strdup (loclabel);
/* See if loclabel might be equal to .Ltext0. If yes,
bump first_loclabel_num_not_at_text_label. */
if (!have_multiple_function_sections
&& in_first_function_p
&& maybe_at_text_label_p)
{
static rtx last_start;
rtx insn;
for (insn = loc_note; insn; insn = previous_insn (insn))
if (insn == last_start)
break;
else if (!NONDEBUG_INSN_P (insn))
continue;
else
{
rtx body = PATTERN (insn);
if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER)
continue;
/* Inline asm could occupy zero bytes. */
else if (GET_CODE (body) == ASM_INPUT
|| asm_noperands (body) >= 0)
continue;
#ifdef HAVE_attr_length
else if (get_attr_min_length (insn) == 0)
continue;
#endif
else
{
/* Assume insn has non-zero length. */
maybe_at_text_label_p = false;
break;
}
}
if (maybe_at_text_label_p)
{
last_start = loc_note;
first_loclabel_num_not_at_text_label = loclabel_num;
}
}
} }
if (!var_loc_p) if (!var_loc_p)
...@@ -20903,6 +20951,59 @@ dwarf2out_begin_function (tree fun) ...@@ -20903,6 +20951,59 @@ dwarf2out_begin_function (tree fun)
set_cur_line_info_table (sec); set_cur_line_info_table (sec);
} }
/* Helper function of dwarf2out_end_function, called only after emitting
the very first function into assembly. Check if some .debug_loc range
might end with a .LVL* label that could be equal to .Ltext0.
In that case we must force using absolute addresses in .debug_loc ranges,
because this range could be .LVLN-.Ltext0 .. .LVLM-.Ltext0 for
.LVLN == .LVLM == .Ltext0, thus 0 .. 0, which is a .debug_loc
list terminator.
Set have_multiple_function_sections to true in that case and
terminate htab traversal. */
static int
find_empty_loc_ranges_at_text_label (void **slot, void *)
{
var_loc_list *entry;
struct var_loc_node *node;
entry = (var_loc_list *) *slot;
node = entry->first;
if (node && node->next && node->next->label)
{
unsigned int i;
const char *label = node->next->label;
char loclabel[MAX_ARTIFICIAL_LABEL_BYTES];
for (i = 0; i < first_loclabel_num_not_at_text_label; i++)
{
ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", i);
if (strcmp (label, loclabel) == 0)
{
have_multiple_function_sections = true;
return 0;
}
}
}
return 1;
}
/* Hook called after emitting a function into assembly.
This does something only for the very first function emitted. */
static void
dwarf2out_end_function (unsigned int)
{
if (in_first_function_p
&& !have_multiple_function_sections
&& first_loclabel_num_not_at_text_label
&& decl_loc_table)
htab_traverse (decl_loc_table, find_empty_loc_ranges_at_text_label,
NULL);
in_first_function_p = false;
maybe_at_text_label_p = false;
}
/* Add OPCODE+VAL as an entry at the end of the opcode array in TABLE. */ /* Add OPCODE+VAL as an entry at the end of the opcode array in TABLE. */
static void static void
......
2013-02-07 Jakub Jelinek <jakub@redhat.com> 2013-02-07 Jakub Jelinek <jakub@redhat.com>
PR debug/56154
* gcc.dg/guality/pr56154-1.c: New test.
* gcc.dg/guality/pr56154-2.c: New test.
* gcc.dg/guality/pr56154-3.c: New test.
* gcc.dg/guality/pr56154-4.c: New test.
* gcc.dg/guality/pr56154-aux.c: New file.
PR tree-optimization/55789 PR tree-optimization/55789
* g++.dg/ipa/inline-3.C: Use cleanup-ipa-dump instead of * g++.dg/ipa/inline-3.C: Use cleanup-ipa-dump instead of
cleanup-tree-dump. cleanup-tree-dump.
......
/* PR debug/56154 */
/* { dg-do run } */
/* { dg-options "-g" } */
/* { dg-additional-sources "pr56154-aux.c" } */
#include "../nop.h"
union U { int a, b; };
volatile int z;
__attribute__((noinline, noclone)) int
foo (int fd, union U x)
{
int result = x.a != 0;
if (fd != 0)
result = x.a == 0;
asm (NOP : : : "memory"); /* { dg-final { gdb-test pr56154-1.c:17 "x.a" "4" } } */
z = x.a;
x.a = 6;
asm (NOP : : : "memory"); /* { dg-final { gdb-test pr56154-1.c:20 "x.a" "6" } } */
return result;
}
void
test_main (void)
{
union U u = { .a = 4 };
foo (0, u);
}
/* PR debug/56154 */
/* { dg-do run } */
/* { dg-options "-g" } */
/* { dg-additional-sources "pr56154-aux.c" } */
#include "../nop.h"
extern void abort (void);
__attribute__((noinline, noclone)) int
foo (int x)
{
asm ("");
x++;
asm ("");
x++;
asm ("");
x++;
asm ("");
x++;
asm ("");
x++;
asm ("");
x++;
asm ("");
x++;
asm ("");
x++;
asm (NOP : : : "memory");
asm (NOP : : : "memory"); /* { dg-final { gdb-test pr56154-2.c:30 "x" "28" } } */
return x;
}
void
test_main (void)
{
if (foo (20) != 28)
abort ();
}
/* PR debug/56154 */
/* { dg-do run } */
/* { dg-options "-g" } */
/* { dg-additional-sources "pr56154-aux.c" } */
#include "../nop.h"
extern void abort (void);
__attribute__((noinline, noclone)) int
foo (int x)
{
x++;
x++;
x++;
x++;
x++;
x++;
x++;
x++;
asm (NOP : : : "memory");
asm (NOP : : : "memory"); /* { dg-final { gdb-test pr56154-3.c:22 "x" "28" } } */
return x;
}
void
test_main (void)
{
if (foo (20) != 28)
abort ();
}
/* PR debug/56154 */
/* { dg-do run } */
/* { dg-options "-g" } */
/* { dg-additional-sources "pr56154-aux.c" } */
#include "../nop.h"
extern void abort (void);
volatile int z;
__attribute__((noinline, noclone)) int
foo (int x)
{
z = 6;
x++;
x++;
x++;
x++;
x++;
x++;
x++;
x++;
asm (NOP : : : "memory");
asm (NOP : : : "memory"); /* { dg-final { gdb-test pr56154-4.c:25 "x" "28" } } */
return x;
}
void
test_main (void)
{
if (foo (20) != 28)
abort ();
}
/* PR debug/56154 */
/* { dg-do compile } */
extern void test_main (void);
int
main ()
{
test_main ();
return 0;
}
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