From 6ce2002b031c923f028fc53cc1ba802483417113 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 8 Jun 2009 19:17:52 +0200 Subject: [PATCH] re PR middle-end/40102 (Revision 147294 caused ICE: verify_cgraph_node) PR middle-end/40102 * cgraph.c (cgraph_create_edge_including_clones): Also asume that the original node might've been modified. * tree-inline.c (copy_bb): Do not assume that all clones are the same. PR middle-end/40102 * g++.dg/torture/pr40102.C: New testcase. From-SVN: r148287 --- gcc/ChangeLog | 7 +++++ gcc/cgraph.c | 5 ++-- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/torture/pr40102.C | 41 ++++++++++++++++++++++++++ gcc/tree-inline.c | 9 ++++-- 5 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr40102.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c31e618ea6a..f6bf148c76e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-06-08 Jan Hubicka + + PR middle-end/40102 + * cgraph.c (cgraph_create_edge_including_clones): Also asume that the + original node might've been modified. + * tree-inline.c (copy_bb): Do not assume that all clones are the same. + 2009-06-08 Jakub Jelinek * tree-object-size.c (addr_object_size): Add OSI argument. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index fe1126bca91..53475d112fc 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -701,8 +701,9 @@ cgraph_create_edge_including_clones (struct cgraph_node *orig, struct cgraph_nod { struct cgraph_node *node; - cgraph_create_edge (orig, callee, stmt, count, freq, loop_depth)->inline_failed = - reason; + if (!cgraph_edge (orig, stmt)) + cgraph_create_edge (orig, callee, stmt, + count, freq, loop_depth)->inline_failed = reason; if (orig->clones) for (node = orig->clones; node != orig;) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c6e7618254d..56dc2bc1189 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-06-08 Jan Hubicka + + PR middle-end/40102 + * g++.dg/torture/pr40102.C: New testcase. + 2009-06-08 Jakub Jelinek * gcc.dg/builtin-object-size-2.c (test1): Adjust expected results. diff --git a/gcc/testsuite/g++.dg/torture/pr40102.C b/gcc/testsuite/g++.dg/torture/pr40102.C new file mode 100644 index 00000000000..49f56b5bc5a --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr40102.C @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +bool foo0(int) { return true; } + +bool foo1(); + +struct A +{ + A(); + ~A(); + + template void bar1(T f) + { + if (f(0)) + foo1(); + } + + template void bar2(T); +}; + +template void A::bar2(T f) +{ + A a, b[1], *p; + + while (foo1()) + { + if (p) + ++p; + if (p && foo1()) + bar1(f); + if (p) + ++p; + } + + if (foo1()) + bar1(f); +} + +void baz() +{ + A().bar2(foo0); +} diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index f79424d9756..18c2c0307de 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1508,11 +1508,14 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, gcc_unreachable (); } + edge = cgraph_edge (id->src_node, orig_stmt); /* Constant propagation on argument done during inlining may create new direct call. Produce an edge for it. */ - if (!edge && is_gimple_call (stmt) - && (fn = gimple_call_fndecl (stmt)) != NULL - && !cgraph_edge (id->dst_node, stmt)) + if ((!edge + || (edge->indirect_call + && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)) + && is_gimple_call (stmt) + && (fn = gimple_call_fndecl (stmt)) != NULL) { struct cgraph_node *dest = cgraph_node (fn);