Bug 91887 - [7 Regression] -fdebug-types-section ICE building chromium
Summary: [7 Regression] -fdebug-types-section ICE building chromium
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 10.0
: P2 major
Target Milestone: 7.5
Assignee: Richard Biener
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2019-09-24 18:59 UTC by Jason Merrill
Modified: 2019-10-24 09:40 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 10.0, 8.3.1, 9.2.1
Known to fail: 7.4.0, 8.3.0, 9.2.0
Last reconfirmed: 2019-09-24 00:00:00


Attachments
unincluded testcase (40.92 KB, application/x-xz)
2019-09-24 18:59 UTC, Jason Merrill
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jason Merrill 2019-09-24 18:59:15 UTC
Created attachment 46938 [details]
unincluded testcase

Compiling this file with -g -fdebug-types-section hits an ICE under lookup_external_ref, because we're trying to look up a DW_TAG_typedef that has no symbol.  We shouldn't be trying to form an external reference to a typedef in the first place; brief attempts to come up with a small testcase have not reproduced the problem.
Comment 1 Marek Polacek 2019-09-24 19:02:38 UTC
ICE reproduced.
Comment 2 Marek Polacek 2019-09-24 19:14:38 UTC
GCC 6 is fine, GCC 7 ICEs so it's a regression.

Started with r240578.
Comment 3 Marek Polacek 2019-09-24 22:33:56 UTC
class A {
public:
  A();
  template <typename U> A(U);
};
template <class> struct B { typedef A type; };
template <class R, typename... Args>
int Bind(R(Args...), typename B<Args>::type...) { return 0; }
void KeepBufferRefs(A, A) { A a, b(Bind(KeepBufferRefs, a, b)); }
Comment 4 Richard Biener 2019-09-25 07:46:45 UTC
I will have a look.
Comment 5 Richard Biener 2019-10-16 08:04:52 UTC
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)
Comment 6 Richard Biener 2019-10-17 06:17:22 UTC
Author: rguenth
Date: Thu Oct 17 06:16:50 2019
New Revision: 277090

URL: https://gcc.gnu.org/viewcvs?rev=277090&root=gcc&view=rev
Log:
2019-10-17  Richard Biener  <rguenther@suse.de>

	PR debug/91887
	* dwarf2out.c (gen_formal_parameter_die): Also try to match
	context_die against a DW_TAG_GNU_formal_parameter_pack parent.

	* g++.dg/debug/dwarf2/pr91887.C: New testcase.

Added:
    trunk/gcc/testsuite/g++.dg/debug/dwarf2/pr91887.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dwarf2out.c
    trunk/gcc/testsuite/ChangeLog
Comment 7 Richard Biener 2019-10-17 06:17:32 UTC
Fixed on trunk sofar.
Comment 8 Richard Biener 2019-10-23 10:32:41 UTC
Author: rguenth
Date: Wed Oct 23 10:32:06 2019
New Revision: 277312

URL: https://gcc.gnu.org/viewcvs?rev=277312&root=gcc&view=rev
Log:
2019-10-23  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2019-10-17  Richard Biener  <rguenther@suse.de>

	PR debug/91887
	* dwarf2out.c (gen_formal_parameter_die): Also try to match
	context_die against a DW_TAG_GNU_formal_parameter_pack parent.

	* g++.dg/debug/dwarf2/pr91887.C: New testcase.

Added:
    branches/gcc-9-branch/gcc/testsuite/g++.dg/debug/dwarf2/pr91887.C
Modified:
    branches/gcc-9-branch/gcc/ChangeLog
    branches/gcc-9-branch/gcc/dwarf2out.c
    branches/gcc-9-branch/gcc/testsuite/ChangeLog
Comment 9 Richard Biener 2019-10-23 12:31:55 UTC
Author: rguenth
Date: Wed Oct 23 12:31:24 2019
New Revision: 277319

URL: https://gcc.gnu.org/viewcvs?rev=277319&root=gcc&view=rev
Log:
2019-10-23  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2019-10-17  Richard Biener  <rguenther@suse.de>

	PR debug/91887
	* dwarf2out.c (gen_formal_parameter_die): Also try to match
	context_die against a DW_TAG_GNU_formal_parameter_pack parent.

	* g++.dg/debug/dwarf2/pr91887.C: New testcase.

	2019-09-19  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/91812
	* tree-ssa-phiprop.c (propagate_with_phi): Do not replace
	volatile loads.

	* gcc.dg/torture/pr91812.c: New testcase.

	2019-09-17  Richard Biener  <rguenther@suse.de>

	PR debug/91772
	* dwarf2out.c (dwarf2out_late_global_decl): If early dwarf
	was missing generate locations only once.

Added:
    branches/gcc-8-branch/gcc/testsuite/g++.dg/debug/dwarf2/pr91887.C
    branches/gcc-8-branch/gcc/testsuite/gcc.dg/torture/pr91812.c
Modified:
    branches/gcc-8-branch/gcc/ChangeLog
    branches/gcc-8-branch/gcc/dwarf2out.c
    branches/gcc-8-branch/gcc/testsuite/ChangeLog
    branches/gcc-8-branch/gcc/tree-ssa-phiprop.c
Comment 10 Richard Biener 2019-10-24 09:39:27 UTC
Author: rguenth
Date: Thu Oct 24 09:38:56 2019
New Revision: 277370

URL: https://gcc.gnu.org/viewcvs?rev=277370&root=gcc&view=rev
Log:
2019-10-24  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2019-10-17  Richard Biener  <rguenther@suse.de>

	PR debug/91887
	* dwarf2out.c (gen_formal_parameter_die): Also try to match
	context_die against a DW_TAG_GNU_formal_parameter_pack parent.

	* g++.dg/debug/dwarf2/pr91887.C: New testcase.

	2019-09-19  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/91812
	* tree-ssa-phiprop.c (propagate_with_phi): Do not replace
	volatile loads.

	* gcc.dg/torture/pr91812.c: New testcase.

Added:
    branches/gcc-7-branch/gcc/testsuite/g++.dg/debug/dwarf2/pr91887.C
    branches/gcc-7-branch/gcc/testsuite/gcc.dg/torture/pr91812.c
Modified:
    branches/gcc-7-branch/gcc/ChangeLog
    branches/gcc-7-branch/gcc/dwarf2out.c
    branches/gcc-7-branch/gcc/testsuite/ChangeLog
    branches/gcc-7-branch/gcc/tree-ssa-phiprop.c
Comment 11 Richard Biener 2019-10-24 09:40:14 UTC
Fixed.