From: hubicka Date: Mon, 8 Jun 2009 17:17:52 +0000 (+0000) Subject: PR middle-end/40102 X-Git-Tag: upstream/4.9.2~35570 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b437daf41754afff274e689c4eddeb291a0e679e;p=platform%2Fupstream%2Flinaro-gcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@148287 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c31e618..f6bf148 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 fe1126b..53475d1 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 c6e7618..56dc2bc 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 0000000..49f56b5 --- /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 f79424d..18c2c03 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);