PR middle-end/40102
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Jun 2009 17:17:52 +0000 (17:17 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Jun 2009 17:17:52 +0000 (17:17 +0000)
* 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

gcc/ChangeLog
gcc/cgraph.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr40102.C [new file with mode: 0644]
gcc/tree-inline.c

index c31e618..f6bf148 100644 (file)
@@ -1,3 +1,10 @@
+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.
index fe1126b..53475d1 100644 (file)
@@ -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;)
index c6e7618..56dc2bc 100644 (file)
@@ -1,3 +1,8 @@
+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.
diff --git a/gcc/testsuite/g++.dg/torture/pr40102.C b/gcc/testsuite/g++.dg/torture/pr40102.C
new file mode 100644 (file)
index 0000000..49f56b5
--- /dev/null
@@ -0,0 +1,41 @@
+/* { 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);
+}
index f79424d..18c2c03 100644 (file)
@@ -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);