From 47cb0d7da16c57888fdc04437530d86f33ee3c1b Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 10 Dec 2009 21:50:47 +0100 Subject: re PR middle-end/42228 (verify_cgraph_node failed:node has wrong clone_of) PR middle-end/42228 PR middle-end/42110 * cgraph.c (cgraph_create_edge_including_clones): Add old_stmt parameter; update edge if it already exists. (cgraph_remove_node): Handle correctly cases where we are removing node having clones. * cgraph.h (cgraph_create_edge_including_clones): Declare. (verify_cgraph_node): Add missing error_found = true code. (cgraph_materialize_all_clones): Remove call edges of dead nodes. * ipa.c (cgraph_remove_unreachable_nodes): Correctly look for master clone; fix double linked list removal. * tree-inline.c (copy_bb): Update cgraph_create_edge_including_clones call; fix frequency of newly created edge. * g++.dg/torture/pr42110.C: new file. From-SVN: r155140 --- gcc/ipa.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'gcc/ipa.c') diff --git a/gcc/ipa.c b/gcc/ipa.c index 1b68a7a..708b800 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -179,11 +179,21 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) first = e->callee; } } + + /* We can freely remove inline clones even if they are cloned, however if + function is clone of real clone, we must keep it around in order to + make materialize_clones produce function body with the changes + applied. */ while (node->clone_of && !node->clone_of->aux && !gimple_has_body_p (node->decl)) { + bool noninline = node->clone_of->decl != node->decl; node = node->clone_of; - node->aux = first; - first = node; + if (noninline) + { + node->aux = first; + first = node; + break; + } } } @@ -244,6 +254,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) node->clone_of->clones = node->next_sibling_clone; if (node->next_sibling_clone) node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone; + node->clone_of = NULL; + node->next_sibling_clone = NULL; + node->prev_sibling_clone = NULL; } else cgraph_remove_node (node); -- cgit v1.1