On 11/14/18 7:33 AM, Richard Biener wrote:
Hmm, there is reference_to_unused () used in a related case. But generally for late emission such references are "OK" and expected to be pruned later by resolve_addr () (which I see we do not call for type units?!). Quote:/* Resolve DW_OP_addr and DW_AT_const_value CONST_STRING arguments to an address in .rodata section if the string literal is emitted there, or remove the containing location list or replace DW_AT_const_value with DW_AT_location and empty location expression, if it isn't found in .rodata. Similarly for SYMBOL_REFs, keep only those that refer to something that has been emitted in the current CU. */ static void resolve_addr (dw_die_ref die) {
That does seem to work. The attached survise bootstrapping on x86_64-linux, ok?
nathan -- Nathan Sidwell
2018-11-14 Nathan Sidwell <[email protected]> PR debug/88006 PR debug/87462 * dwarf2out.c (dwarf2out_finish): Apply resolve_addr to comdat type list. * g++.dg/debug/dwarf2/pr87462.C: New. * g++.dg/debug/dwarf2/pr88006.C: New. Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 266082) +++ dwarf2out.c (working copy) @@ -31182,6 +31182,8 @@ dwarf2out_finish (const char *filename) FOR_EACH_CHILD (die, c, gcc_assert (! c->die_mark)); } #endif + for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next) + resolve_addr (ctnode->root_die); resolve_addr (comp_unit_die ()); move_marked_base_types (); Index: testsuite/g++.dg/debug/dwarf2/pr87462.C =================================================================== --- testsuite/g++.dg/debug/dwarf2/pr87462.C (revision 0) +++ testsuite/g++.dg/debug/dwarf2/pr87462.C (working copy) @@ -0,0 +1,20 @@ +// { dg-additional-options "-dA -std=gnu++17 -gdwarf-4 -O1 -fdebug-types-section" } +// reject .pseudo label, but "label" is ok. +// { dg-final { scan-assembler-not "\[^L\"\]_ZN5Test18testFuncEv" } } +// undefined ref to _ZN5Test18testFuncEv + +class Test1 { +public: + static int testFunc() { return 1; } +}; + +template <typename T, + T (*funcImpl)()> +class TestWrapper { +public: + static T func() __attribute((noinline)) { return (*funcImpl)(); } +}; + +int main() { + return TestWrapper<int, &Test1::testFunc>::func(); +} Index: testsuite/g++.dg/debug/dwarf2/pr88006.C =================================================================== --- testsuite/g++.dg/debug/dwarf2/pr88006.C (revision 0) +++ testsuite/g++.dg/debug/dwarf2/pr88006.C (working copy) @@ -0,0 +1,39 @@ +// { dg-additional-options "-dA -std=gnu++17 -gdwarf-4 -O1 -fdebug-types-section" } +// reject .pseudo label, but "label" is ok. +// { dg-final { scan-assembler-not "\[^\"\]_ZN3Foo4mfunEv" } } +// undefined ref to _ZN3Foo4mfunEv + +struct Foo { + void mfun () {} +}; + +struct A { static constexpr bool Value = false; }; + +template <bool> struct B { typedef int Type; }; + +class Arg +{ + template <typename Unused> struct Local : A {}; + +public: + template <typename Init, typename = typename B<Local<Init>::Value>::Type> + Arg (Init) {} +}; + +class Lambda { + static constexpr int Unused = 0; + +public: + Lambda (Arg); +}; + +// Generated ref to Foo::mfun in the type die of an instantiation of this +template <void (Foo::*unused)()> struct Callable {}; + +class I { + I() : lamb ([this] {}) {} + + Lambda lamb; + + Callable<&Foo::mfun> bm; +};
