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.
ICE reproduced.
GCC 6 is fine, GCC 7 ICEs so it's a regression. Started with r240578.
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)); }
I will have a look.
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)
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
Fixed on trunk sofar.
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
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
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
Fixed.