re PR tree-optimization/55264 (ICE: in ipa_make_edge_direct_to_target, at ipa-prop...
authorMartin Jambor <mjambor@suse.cz>
Thu, 17 Jan 2013 11:43:14 +0000 (12:43 +0100)
committerMartin Jambor <jamborm@gcc.gnu.org>
Thu, 17 Jan 2013 11:43:14 +0000 (12:43 +0100)
2013-01-17  Martin Jambor  <mjambor@suse.cz>

PR tree-optimizations/55264
* ipa-inline-transform.c (can_remove_node_now_p_1): Never return true
for virtual methods.
* ipa.c (symtab_remove_unreachable_nodes): Never return true for
virtual methods before inlining is over.
* cgraph.h (cgraph_only_called_directly_or_aliased_p): Return false for
virtual functions.
* cgraphclones.c (cgraph_create_virtual_clone): Mark clones as
non-virtual.

testsuite/
* g++.dg/ipa/pr55264.C: New test.

From-SVN: r195262

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphclones.c
gcc/ipa-inline-transform.c
gcc/ipa.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr55264.C [new file with mode: 0644]

index 41a4b42b9930199c87f4521a7db27b12799fff7d..6475b3c081e697833e097839c2f204c1d5598a06 100644 (file)
@@ -1,3 +1,15 @@
+2013-01-17  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimizations/55264
+       * ipa-inline-transform.c (can_remove_node_now_p_1): Never return true
+       for virtual methods.
+       * ipa.c (symtab_remove_unreachable_nodes): Never return true for
+       virtual methods before inlining is over.
+       * cgraph.h (cgraph_only_called_directly_or_aliased_p): Return false for
+       virtual functions.
+       * cgraphclones.c (cgraph_create_virtual_clone): Mark clones as
+       non-virtual.
+
 2013-01-16  Vladimir Makarov  <vmakarov@redhat.com>
 
        PR rtl-optimization/56005
index 875957016545eb29876cbdfcbd584d73814ec556..5df7fb478b4a6c38addd5f7b89efbafc3456be43 100644 (file)
@@ -1164,6 +1164,7 @@ cgraph_only_called_directly_or_aliased_p (struct cgraph_node *node)
   gcc_assert (!node->global.inlined_to);
   return (!node->symbol.force_output && !node->symbol.address_taken
          && !node->symbol.used_from_other_partition
+         && !DECL_VIRTUAL_P (node->symbol.decl)
          && !DECL_STATIC_CONSTRUCTOR (node->symbol.decl)
          && !DECL_STATIC_DESTRUCTOR (node->symbol.decl)
          && !node->symbol.externally_visible);
index 611bb811e578caf2defe1a58a920bf3ac2f5b129..30d02d11dd92fc9ff8227a751668929f13bce778 100644 (file)
@@ -319,6 +319,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
   TREE_PUBLIC (new_node->symbol.decl) = 0;
   DECL_COMDAT (new_node->symbol.decl) = 0;
   DECL_WEAK (new_node->symbol.decl) = 0;
+  DECL_VIRTUAL_P (new_node->symbol.decl) = 0;
   DECL_STATIC_CONSTRUCTOR (new_node->symbol.decl) = 0;
   DECL_STATIC_DESTRUCTOR (new_node->symbol.decl) = 0;
   new_node->clone.tree_map = tree_map;
index 0fb8940b82b5cd3128dc17e5cd0e66418857fd44..cac20fecc3b53af578947f808bac89f1854bd281 100644 (file)
@@ -92,9 +92,7 @@ can_remove_node_now_p_1 (struct cgraph_node *node)
             those only after all devirtualizable virtual calls are processed.
             Lacking may edges in callgraph we just preserve them post
             inlining.  */
-         && (!DECL_VIRTUAL_P (node->symbol.decl)
-             || (!DECL_COMDAT (node->symbol.decl)
-                 && !DECL_EXTERNAL (node->symbol.decl)))
+         && !DECL_VIRTUAL_P (node->symbol.decl)
          /* During early inlining some unanalyzed cgraph nodes might be in the
             callgraph and they might reffer the function in question.  */
          && !cgraph_new_nodes);
index f87e03b7e04f53c9306c6dd5c02da5261d8acb32..a9b8fb419882c04bda8417a0553636bdc05db705 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -241,8 +241,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
        && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
            /* Keep around virtual functions for possible devirtualization.  */
            || (before_inlining_p
-               && DECL_VIRTUAL_P (node->symbol.decl)
-               && (DECL_COMDAT (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl)))))
+               && DECL_VIRTUAL_P (node->symbol.decl))))
       {
         gcc_assert (!node->global.inlined_to);
        pointer_set_insert (reachable, node);
index 7572696951e7bf3983811047db7a20da90ed04dd..f6bef191bbe00731926cbfcfd47e5b9d8ee85117 100644 (file)
@@ -1,3 +1,8 @@
+2013-01-17  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimizations/55264
+       * g++.dg/ipa/pr55264.C: New test.
+
 2013-01-16  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/55983
diff --git a/gcc/testsuite/g++.dg/ipa/pr55264.C b/gcc/testsuite/g++.dg/ipa/pr55264.C
new file mode 100644 (file)
index 0000000..cf54d6a
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-early-inlining -fno-weak"  } */
+
+struct S
+{
+  S();
+  virtual inline void foo ()
+  {
+    foo();
+  }
+};
+
+void
+B ()
+{
+  S().foo ();
+}