From f980dfdb8ceb8ddd2683787120b800c8584121ee Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 7 Feb 2013 15:48:39 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 13 ++++ gcc/dwarf2out.c | 103 ++++++++++++++++++++++++++++- gcc/testsuite/ChangeLog | 7 ++ gcc/testsuite/gcc.dg/guality/pr56154-1.c | 29 ++++++++ gcc/testsuite/gcc.dg/guality/pr56154-2.c | 39 +++++++++++ gcc/testsuite/gcc.dg/guality/pr56154-3.c | 31 +++++++++ gcc/testsuite/gcc.dg/guality/pr56154-4.c | 34 ++++++++++ gcc/testsuite/gcc.dg/guality/pr56154-aux.c | 11 +++ 8 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/guality/pr56154-1.c create mode 100644 gcc/testsuite/gcc.dg/guality/pr56154-2.c create mode 100644 gcc/testsuite/gcc.dg/guality/pr56154-3.c create mode 100644 gcc/testsuite/gcc.dg/guality/pr56154-4.c create mode 100644 gcc/testsuite/gcc.dg/guality/pr56154-aux.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b7914b5..a1ad361 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2013-02-07 Jakub Jelinek + + 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 PR rtl-optimization/56178 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 06cfb18..13c31ad 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -2351,6 +2351,7 @@ static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree, static void dwarf2out_abstract_function (tree); static void dwarf2out_var_location (rtx); static void dwarf2out_begin_function (tree); +static void dwarf2out_end_function (unsigned int); static void dwarf2out_set_name (tree, tree); /* The debug hooks structure. */ @@ -2378,7 +2379,7 @@ const struct gcc_debug_hooks dwarf2_debug_hooks = #endif dwarf2out_end_epilogue, dwarf2out_begin_function, - debug_nothing_int, /* end_function */ + dwarf2out_end_function, /* end_function */ dwarf2out_function_decl, /* function_decl */ dwarf2out_global_decl, dwarf2out_type_decl, /* type_decl */ @@ -20627,6 +20628,14 @@ dwarf2out_set_name (tree decl, tree name) 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 use it to drop labels in the right places, and throw the location in our lookup table. */ @@ -20734,6 +20743,45 @@ dwarf2out_var_location (rtx loc_note) ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LVL", loclabel_num); loclabel_num++; 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) @@ -20903,6 +20951,59 @@ dwarf2out_begin_function (tree fun) 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. */ static void diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffa9cc3..c024e08 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2013-02-07 Jakub Jelinek + 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 * g++.dg/ipa/inline-3.C: Use cleanup-ipa-dump instead of cleanup-tree-dump. diff --git a/gcc/testsuite/gcc.dg/guality/pr56154-1.c b/gcc/testsuite/gcc.dg/guality/pr56154-1.c new file mode 100644 index 0000000..4f02bc9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr56154-1.c @@ -0,0 +1,29 @@ +/* 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); +} diff --git a/gcc/testsuite/gcc.dg/guality/pr56154-2.c b/gcc/testsuite/gcc.dg/guality/pr56154-2.c new file mode 100644 index 0000000..6c1d5d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr56154-2.c @@ -0,0 +1,39 @@ +/* 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 (); +} diff --git a/gcc/testsuite/gcc.dg/guality/pr56154-3.c b/gcc/testsuite/gcc.dg/guality/pr56154-3.c new file mode 100644 index 0000000..095dce9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr56154-3.c @@ -0,0 +1,31 @@ +/* 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 (); +} diff --git a/gcc/testsuite/gcc.dg/guality/pr56154-4.c b/gcc/testsuite/gcc.dg/guality/pr56154-4.c new file mode 100644 index 0000000..bfe7338 --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr56154-4.c @@ -0,0 +1,34 @@ +/* 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 (); +} diff --git a/gcc/testsuite/gcc.dg/guality/pr56154-aux.c b/gcc/testsuite/gcc.dg/guality/pr56154-aux.c new file mode 100644 index 0000000..131173c --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr56154-aux.c @@ -0,0 +1,11 @@ +/* PR debug/56154 */ +/* { dg-do compile } */ + +extern void test_main (void); + +int +main () +{ + test_main (); + return 0; +} -- 2.7.4