@@ -1935,6 +1935,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " Clone of %s/%i\n",
node->clone_of->asm_name (),
node->clone_of->order);
+ if (node->former_clone_of == error_mark_node)
+ fprintf (f, " Body removed by symtab_remove_unreachable_nodes\n");
if (cgraph_function_flags_ready)
fprintf (f, " Availability: %s\n",
cgraph_availability_names [cgraph_function_body_availability (node)]);
@@ -2602,7 +2604,10 @@ verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
/* We do not know if a node from a different partition is an alias or what it
aliases and therefore cannot do the former_clone_of check reliably. */
- if (!node || node->in_other_partition || e->callee->in_other_partition)
+ if (!node
+ || node->former_clone_of == error_mark_node
+ || node->in_other_partition
+ || e->callee->in_other_partition)
return false;
node = cgraph_function_or_thunk_node (node, NULL);
@@ -914,7 +914,8 @@ cgraph_materialize_clone (struct cgraph_node *node)
{
bitmap_obstack_initialize (NULL);
node->former_clone_of = node->clone_of->decl;
- if (node->clone_of->former_clone_of)
+ if (node->clone_of->former_clone_of
+ && node->clone_of->former_clone_of != error_mark_node)
node->former_clone_of = node->clone_of->former_clone_of;
/* Copy the OLD_VERSION_NODE function tree to the new version. */
tree_function_versioning (node->clone_of->decl, node->decl,
@@ -484,6 +484,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
{
if (file)
fprintf (file, " %s", node->name ());
+ gcc_assert (!node->former_clone_of);
+ node->former_clone_of = error_mark_node;
node->analyzed = false;
node->definition = false;
node->cpp_implicit_alias = false;
new file mode 100644
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+template <class> class A {
+protected:
+ void m_fn2();
+ ~A() { m_fn2(); }
+ virtual void m_fn1();
+};
+
+class D : A<int> {};
+template <class Key> void A<Key>::m_fn2() {
+ m_fn1();
+ m_fn1();
+ m_fn1();
+}
+
+#pragma interface
+class B {
+ D m_cellsAlreadyProcessed;
+ D m_cellsNotToProcess;
+
+public:
+ virtual ~B() {}
+ void m_fn1();
+};
+
+class C {
+ unsigned long m_fn1();
+ B m_fn2();
+ unsigned long m_fn3();
+};
+unsigned long C::m_fn1() {
+CellHierarchy:
+ m_fn2().m_fn1();
+}
+
+unsigned long C::m_fn3() {
+CellHierarchy:
+ m_fn2().m_fn1();
+}