Hi Jason.
For class scoped static functions:
class C {
public:
static void moo () {}
};
...we are calling gen_subprogram on moo() the usual handful of times
(during early dwarf): once as a member of C and once because moo() is a
reachable function. However, on the second time, we reuse the cached
DIE and merely remove the DW_AT_declaration attribute:
/* Clear out the declaration attribute, but leave the
parameters so they can be augmented with location
information later. */
remove_AT (subr_die, DW_AT_declaration);
This causes us to reuse the DIE from within the class, instead of adding
a specification of this cached DIE.
With the attached tweak we fix this problem, and about a hundred gdb
regressions. This IMHO is a "Good Thing" :).
Would you be so kind as to look at this two-liner to make sure you're OK
with it?
Thanks.
Aldy
commit cec08d43caffbf086720ac3994d068010dc103c9
Author: Aldy Hernandez <al...@redhat.com>
Date: Fri Mar 20 09:55:31 2015 -0700
Handle specification of class scoped static functions.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 8884afd..1325dfe 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -18770,7 +18770,20 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
struct dwarf_file_data * file_index = lookup_filename (s.file);
if (((is_cu_die (old_die->die_parent)
|| context_die == NULL
- || dumped_early)
+ || (dumped_early
+ /* For class scoped static functions, the dumped early
+ version was the declaration, whereas the next time
+ around with a different context should be the
+ specification. In this case, avoid reusing the
+ DIE, but generate a specification below. E.g.:
+
+ class C {
+ public:
+ static void moo () {}
+ };
+ */
+ && (!is_cu_die (context_die)
+ || !class_or_namespace_scope_p (old_die->die_parent))))
&& (DECL_ARTIFICIAL (decl)
|| (get_AT_file (old_die, DW_AT_decl_file) == file_index
&& (get_AT_unsigned (old_die, DW_AT_decl_line)