===================================================================
@@ -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);
===================================================================
@@ -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();
+}
+}
+
===================================================================
@@ -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 &) {}
+}
+
===================================================================
@@ -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);