re PR middle-end/40102 (Revision 147294 caused ICE: verify_cgraph_node)
authorJan Hubicka <jh@suse.cz>
Mon, 8 Jun 2009 17:17:52 +0000 (19:17 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 8 Jun 2009 17:17:52 +0000 (17:17 +0000)
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
gcc/cgraph.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr40102.C [new file with mode: 0644]
gcc/tree-inline.c

index c31e618ea6a1d0c22173d0ef08548b1f85bcc9a3..f6bf148c76e2e39e4dedc58fd8f2188da8367806 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 fe1126bca919c978288bdce18cce8ee964343457..53475d112fc61e85af536cce7722643102e70e20 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 c6e7618254d24fe8a13a705c6362a0b40f35435d..56dc2bc1189650961ac3dedf8796480e5c5a1f52 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 f79424d9756bcae7d8ea7e506d9df9e8019132d4..18c2c0307dec9c50f7a47a75eb23b715de863fd3 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);