* g++.dg/lto/pr45621.h : New.
* g++.dg/lto/pr45621_0.C: New.
* g++.dg/lto/pr45621_1.C: New.
* cgraph.c (cgraph_update_edges_for_call_stmt_node): When new call is
redirected to clone, be happy.
* cgraph.h (cgraph node): Enable former_clone_of unconditinally.
* cgraphunit.c (verify_cgraph_node, cgraph_materialize_clone): Handle
former_clone_of unconditinally.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165492
138bc75d-0d04-0410-961f-
82ee72b054a4
+2010-10-14 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/45621
+ * cgraph.c (cgraph_update_edges_for_call_stmt_node): When new call is
+ redirected to clone, be happy.
+ * cgraph.h (cgraph node): Enable former_clone_of unconditinally.
+ * cgraphunit.c (verify_cgraph_node, cgraph_materialize_clone): Handle
+ former_clone_of unconditinally.
+
2010-10-14 Iain Sandoe <iains@gcc.gnu.org>
merge from FSF apple 'trunk' branch.
{
/* See if the edge is already there and has the correct callee. It
might be so because of indirect inlining has already updated
- it. */
- if (new_call && e->callee && e->callee->decl == new_call)
- return;
+ it. We also might've cloned and redirected the edge. */
+ if (new_call && e->callee)
+ {
+ struct cgraph_node *callee = e->callee;
+ while (callee)
+ {
+ if (callee->decl == new_call
+ || callee->former_clone_of == new_call)
+ return;
+ callee = callee->clone_of;
+ }
+ }
/* Otherwise remove edge and create new one; we can't simply redirect
since function has changed, so inline plan and other information
/* For functions with many calls sites it holds map from call expression
to the edge to speed up cgraph_edge function. */
htab_t GTY((param_is (struct cgraph_edge))) call_site_hash;
-#ifdef ENABLE_CHECKING
- /* Declaration node used to be clone of. Used for checking only.
- We must skip it or we get references from release checking GGC files. */
- tree GTY ((skip)) former_clone_of;
-#endif
+ /* Declaration node used to be clone of. */
+ tree former_clone_of;
PTR GTY ((skip)) aux;
debug_tree (e->callee->decl);
error_found = true;
}
-#ifdef ENABLE_CHECKING
else if (!e->callee->global.inlined_to
&& decl
&& cgraph_get_node (decl)
debug_tree (decl);
error_found = true;
}
-#endif
}
else if (decl)
{
cgraph_materialize_clone (struct cgraph_node *node)
{
bitmap_obstack_initialize (NULL);
-#ifdef ENABLE_CHECKING
node->former_clone_of = node->clone_of->decl;
if (node->clone_of->former_clone_of)
node->former_clone_of = node->clone_of->former_clone_of;
-#endif
/* Copy the OLD_VERSION_NODE function tree to the new version. */
tree_function_versioning (node->clone_of->decl, node->decl,
node->clone.tree_map, true,
+2010-10-14 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/45621
+ * g++.dg/lto/pr45621.h : New.
+ * g++.dg/lto/pr45621_0.C: New.
+ * g++.dg/lto/pr45621_1.C: New.
+
2010-10-14 Iain Sandoe <iains@gcc.gnu.org>
* objc.dg/property: New.
--- /dev/null
+struct S
+{
+ void m ();
+ virtual void v1 ();
+ virtual void v2 ();
+};
+
+extern S s;
--- /dev/null
+// { dg-lto-do assemble }
+// { dg-extra-ld-options "-O2 -fipa-cp-clone -flto -nostdlib -r" }
+#include "pr45621.h"
+
+void
+foo ()
+{
+ s.v1 ();
+ s.m ();
+}
--- /dev/null
+#include "pr45621.h"
+
+void
+S::v1 ()
+{
+ v2 ();
+}
+
+void
+S::m ()
+{
+ v1 ();
+}