https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91887

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue seems to be that during late dwarf2out_function_decl we no longer
identify formal parameter packs as such, generating a bogus new
DW_TAG_formal_parameter via

          if (generic_decl_parm
              && lang_hooks.function_parameter_pack_p (generic_decl_parm))
            gen_formal_parameter_pack_die (generic_decl_parm,
                                           parm, subr_die,
                                           &parm);
          else if (parm)
            {
              dw_die_ref parm_die = gen_decl_die (parm, NULL, NULL, subr_die);

and the latter doesn't re-use the DIE because

      /* If the contexts differ, we may not be talking about the same
         thing.
         ???  When in LTO the DIE parent is the "abstract" copy and the
         context_die is the specification "copy".  But this whole block
         should eventually be no longer needed.  */
      if (parm_die && parm_die->die_parent != context_die && !in_lto_p)
        {

but then parm_die->die_parent is DW_TAG_GNU_formal_parameter_pack while
context_die is DW_TAG_subprogram.

We go different routes here because that generic_decl_parm thing is only
handled during early_dwarf:

      /* Generate DIEs to represent all known formal parameters.  */
      tree parm = DECL_ARGUMENTS (decl); 
      tree generic_decl = early_dwarf
        ? lang_hooks.decls.get_generic_function_decl (decl) : NULL;
      tree generic_decl_parm = generic_decl
                                ? DECL_ARGUMENTS (generic_decl)
                                : NULL;

The question is how the DWARF should look like and whether those
parameter pack DIEs should be annotated late with locations at all
and if not how we can identify the PARM_DECLs that need no such handling.
Since both paths create a DIE for 'parm' either one has to deal with
"completing" the other.

In any case, creatig a new type DIE late as we do here wrecks with the comdat
type handling.

So I think we need to adjust

      /* If the contexts differ, we may not be talking about the same
         thing.
         ???  When in LTO the DIE parent is the "abstract" copy and the
         context_die is the specification "copy".  But this whole block
         should eventually be no longer needed.  */
      if (parm_die && parm_die->die_parent != context_die && !in_lto_p)

to consider a formal parameter pack parent.  Note the comment is
a bit misleading since the handling is needed for the case we
are creating a concrete instance DIE (which we do late) when
the original DIE was the abstract copy used for inline instances,
the inline copies get handled by

  /* If we have a previously generated DIE, use it, unless this is an
     concrete instance (origin != NULL), in which case we need a new
     DIE with a corresponding DW_AT_abstract_origin.  */
  bool reusing_die;
  if (parm_die && origin == NULL)
    reusing_die = true;


So - a fix could look like

Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c     (revision 277053)
+++ gcc/dwarf2out.c     (working copy)
@@ -22284,19 +22284,18 @@ gen_formal_parameter_die (tree node, tre
       /* If the contexts differ, we may not be talking about the same
         thing.
         ???  When in LTO the DIE parent is the "abstract" copy and the
-        context_die is the specification "copy".  But this whole block
-        should eventually be no longer needed.  */
-      if (parm_die && parm_die->die_parent != context_die && !in_lto_p)
+        context_die is the specification "copy".  */
+      if (parm_die
+         && parm_die->die_parent != context_die
+         && (parm_die->die_parent->die_tag != DW_TAG_GNU_formal_parameter_pack
+             || parm_die->die_parent->die_parent != context_die)
+         && !in_lto_p)
        {
-         if (!DECL_ABSTRACT_P (node))
-           {
-             /* This can happen when creating an inlined instance, in
-                which case we need to create a new DIE that will get
-                annotated with DW_AT_abstract_origin.  */
-             parm_die = NULL;
-           }
-         else
-           gcc_unreachable ();
+         gcc_assert (!DECL_ABSTRACT_P (node));
+         /* This can happen when creating a concrete instance, in
+            which case we need to create a new DIE that will get
+            annotated with DW_AT_abstract_origin.  */
+         parm_die = NULL;
        }

       if (parm_die && parm_die->die_parent == NULL)

Reply via email to