Hi, this patch fixes confusion of cgraph_node::get_untransformed_body about thunks so we do not try to stream them in twice.
Honza * cgraphunit.c (cgraph_node::expand_thunk): When forcing gimple assume that the node has body. * cgraph.c (cgraph_node::get_untransformed_body): Use gimple_body_p check. * g++.dg/lto/pr69133_0.C: New testcase. * g++.dg/lto/pr69133_1.C: New testcase. Index: cgraphunit.c =================================================================== --- cgraphunit.c (revision 232466) +++ cgraphunit.c (working copy) @@ -1664,7 +1666,9 @@ cgraph_node::expand_thunk (bool output_a greturn *ret; bool alias_is_noreturn = TREE_THIS_VOLATILE (alias); - if (in_lto_p) + /* We may be called from expand_thunk that releses body except for + DECL_ARGUMENTS. In this case force_gimple_thunk is true. */ + if (in_lto_p && !force_gimple_thunk) get_untransformed_body (); a = DECL_ARGUMENTS (thunk_fndecl); Index: testsuite/g++.dg/lto/pr69133_0.C =================================================================== --- testsuite/g++.dg/lto/pr69133_0.C (revision 0) +++ testsuite/g++.dg/lto/pr69133_0.C (revision 0) @@ -0,0 +1,19 @@ +// { dg-lto-do link } +// { dg-lto-options { { -flto -O2 } } } +// { dg-extra-ld-options "-r -nostdlib -flto -flto-partition=none -O2" } +namespace xercesc_3_1 { +class XMLEntityHandler { +public: + virtual ~XMLEntityHandler(); + virtual void m_fn1(); + virtual bool m_fn2(); + virtual void m_fn3(); + virtual int m_fn4(); + virtual void m_fn5(); +} * a; +void fn1() { + a->m_fn5(); + a->m_fn1(); +} +} + Index: testsuite/g++.dg/lto/pr69133_1.C =================================================================== --- testsuite/g++.dg/lto/pr69133_1.C (revision 0) +++ testsuite/g++.dg/lto/pr69133_1.C (revision 0) @@ -0,0 +1,22 @@ +namespace xercesc_3_1 { +class A { + virtual void m_fn1(); +}; +class XMLEntityHandler { +public: + virtual ~XMLEntityHandler(); + virtual void m_fn2(const int &); + virtual bool m_fn3(); + virtual void m_fn4(); + virtual int m_fn5() = 0; + virtual void m_fn6(const int &); +}; +class B : A, XMLEntityHandler {}; +class C : B { + void m_fn2(const int &); + void m_fn6(const int &); +}; +void C::m_fn2(const int &) {} +void C::m_fn6(const int &) {} +} + Index: cgraph.c =================================================================== --- cgraph.c (revision 232466) +++ cgraph.c (working copy) @@ -3305,10 +3300,12 @@ cgraph_node::get_untransformed_body (voi size_t len; tree decl = this->decl; - if (DECL_RESULT (decl)) + /* Check if body is already there. Either we have gimple body or + the function is thunk and in that case we set DECL_ARGUMENTS. */ + if (DECL_ARGUMENTS (decl) || gimple_has_body_p (decl)) return false; - gcc_assert (in_lto_p); + gcc_assert (in_lto_p && !DECL_RESULT (decl)); timevar_push (TV_IPA_LTO_GIMPLE_IN);