Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard.
2016-10-12 Richard Biener <rguent...@suse.de> PR debug/77947 * cgraphunit.c (analyze_functions): Preserve cgraph nodes function context. * g++.dg/torture/pr77947.C: New testcase. Index: gcc/cgraphunit.c =================================================================== --- gcc/cgraphunit.c (revision 241033) +++ gcc/cgraphunit.c (working copy) @@ -1117,15 +1117,22 @@ analyze_functions (bool first_time) } /* If decl is a clone of an abstract function, - mark that abstract function so that we don't release its body. - The DECL_INITIAL() of that abstract function declaration - will be later needed to output debug info. */ + mark that abstract function so that we don't release its body. + The DECL_INITIAL() of that abstract function declaration + will be later needed to output debug info. */ if (DECL_ABSTRACT_ORIGIN (decl)) { cgraph_node *origin_node = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (decl)); origin_node->used_as_abstract_origin = true; } + /* Preserve a functions function context node. It will + later be needed to output debug info. */ + if (tree fn = decl_function_context (decl)) + { + cgraph_node *origin_node = cgraph_node::get_create (fn); + enqueue_node (origin_node); + } } else { Index: gcc/testsuite/g++.dg/torture/pr77947.C =================================================================== --- gcc/testsuite/g++.dg/torture/pr77947.C (revision 0) +++ gcc/testsuite/g++.dg/torture/pr77947.C (revision 0) @@ -0,0 +1,29 @@ +// { dg-do compile } +// { dg-additional-options "-g" } + +class A +{ +public: + virtual bool m_fn1 () const = 0; +}; +class B +{ + const A *m_fn2 () const; +}; +inline const A * +B::m_fn2 () const +{ + class C : A + { + bool + m_fn1 () const + { + } + C () {} + }; +} +void +fn1 (A &p1) +{ + p1.m_fn1 (); +}