2018-11-14 Nathan Sidwell PR debug/88006 PR debug/87462 * dwarf2out.c (const_ok_for_output_1): Check symtab for internal decls. * 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) @@ -14480,13 +14472,15 @@ const_ok_for_output_1 (rtx rtl) if (SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE) return false; - /* Avoid references to external symbols in debug info, on several targets - the linker might even refuse to link when linking a shared library, - and in many other cases the relocations for .debug_info/.debug_loc are - dropped, so the address becomes zero anyway. Hidden symbols, guaranteed - to be defined within the same shared library or executable are fine. */ if (SYMBOL_REF_EXTERNAL_P (rtl)) { + /* Avoid references to external symbols in debug info, on + several targets the linker might even refuse to link when + linking a shared library, and in many other cases the + relocations for .debug_info/.debug_loc are dropped, so the + address becomes zero anyway. Hidden symbols, guaranteed to + be defined within the same shared library or executable are + fine. */ tree decl = SYMBOL_REF_DECL (rtl); if (decl == NULL || !targetm.binds_local_p (decl)) @@ -14496,6 +14490,18 @@ const_ok_for_output_1 (rtx rtl) return false; } } + else + { + /* Internal decls are not necessarily emitted -- they could be + inlined or whatever. */ + if (tree decl = SYMBOL_REF_DECL (rtl)) + if (!symtab_node::get (decl)) + { + expansion_failed (NULL_TREE, rtl, + "Symbol not emitted in current TU.\n"); + return false; + } + } return true; } 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 +class TestWrapper { +public: + static T func() __attribute((noinline)) { return (*funcImpl)(); } +}; + +int main() { + return TestWrapper::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 struct B { typedef int Type; }; + +class Arg +{ + template struct Local : A {}; + +public: + template ::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 struct Callable {}; + +class I { + I() : lamb ([this] {}) {} + + Lambda lamb; + + Callable<&Foo::mfun> bm; +};