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)

Reply via email to