+2009-06-08 Jan Hubicka <jh@suse.cz>
+
+ 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 <jakub@redhat.com>
* tree-object-size.c (addr_object_size): Add OSI argument.
{
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;)
+2009-06-08 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/40102
+ * g++.dg/torture/pr40102.C: New testcase.
+
2009-06-08 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/builtin-object-size-2.c (test1): Adjust expected results.
--- /dev/null
+/* { dg-do compile } */
+bool foo0(int) { return true; }
+
+bool foo1();
+
+struct A
+{
+ A();
+ ~A();
+
+ template<typename T> void bar1(T f)
+ {
+ if (f(0))
+ foo1();
+ }
+
+ template<typename T> void bar2(T);
+};
+
+template<typename T> 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);
+}
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);