PR ipa/66223
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 19 Jan 2016 16:49:50 +0000 (16:49 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 19 Jan 2016 16:49:50 +0000 (16:49 +0000)
* ipa-devirt.c (is_cxa_pure_virtual_p): New function.
(maybe_record_node): Record cxa_pure_virtual as the only possible
target if there are not ohter candidates.
(possible_polymorphic_call_target_p): Accept cxa_pure_virtual.

* g++.dg/ipa/devirt-50.C: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232572 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ipa-devirt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/devirt-50.C [new file with mode: 0644]

index 1e753ef..5c4a132 100644 (file)
@@ -1,3 +1,11 @@
+2016-01-19  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/66223
+       * ipa-devirt.c (is_cxa_pure_virtual_p): New function.
+       (maybe_record_node): Record cxa_pure_virtual as the only possible
+       target if there are not ohter candidates.
+       (possible_polymorphic_call_target_p): Accept cxa_pure_virtual.
+
 2016-01-19  Richard Biener  <rguenther@suse.de>
 
        * hsa-gen.c (get_memory_order_name): Use MEMMODEL_ constants.
index a3cb08f..736858e 100644 (file)
@@ -2327,6 +2327,17 @@ referenced_from_vtable_p (struct cgraph_node *node)
   return found;
 }
 
+/* Return if TARGET is cxa_pure_virtual.  */
+
+static bool
+is_cxa_pure_virtual_p (tree target)
+{
+  return target && TREE_CODE (TREE_TYPE (target)) != METHOD_TYPE
+        && DECL_NAME (target)
+        && !strcmp (IDENTIFIER_POINTER (DECL_NAME (target)),
+                    "__cxa_pure_virtual");
+}
+
 /* If TARGET has associated node, record it in the NODES array.
    CAN_REFER specify if program can refer to the target directly.
    if TARGET is unknown (NULL) or it can not be inserted (for example because
@@ -2341,11 +2352,12 @@ maybe_record_node (vec <cgraph_node *> &nodes,
 {
   struct cgraph_node *target_node, *alias_target;
   enum availability avail;
+  bool pure_virtual = is_cxa_pure_virtual_p (target);
 
-  /* cxa_pure_virtual and __builtin_unreachable do not need to be added into
+  /* __builtin_unreachable do not need to be added into
      list of targets; the runtime effect of calling them is undefined.
      Only "real" virtual methods should be accounted.  */
-  if (target && TREE_CODE (TREE_TYPE (target)) != METHOD_TYPE)
+  if (target && TREE_CODE (TREE_TYPE (target)) != METHOD_TYPE && !pure_virtual)
     return;
 
   if (!can_refer)
@@ -2388,6 +2400,7 @@ maybe_record_node (vec <cgraph_node *> &nodes,
      ??? Maybe it would make sense to be more aggressive for LTO even
      elsewhere.  */
   if (!flag_ltrans
+      && !pure_virtual
       && type_in_anonymous_namespace_p (DECL_CONTEXT (target))
       && (!target_node
           || !referenced_from_vtable_p (target_node)))
@@ -2401,6 +2414,20 @@ maybe_record_node (vec <cgraph_node *> &nodes,
     {
       gcc_assert (!target_node->global.inlined_to);
       gcc_assert (target_node->real_symbol_p ());
+      /* Only add pure virtual if it is the only possible target.  This way
+        we will preserve the diagnostics about pure virtual called in many
+        cases without disabling optimization in other.  */
+      if (pure_virtual)
+       {
+         if (nodes.length ())
+           return;
+       }
+      /* If we found a real target, take away cxa_pure_virtual.  */
+      else if (!pure_virtual && nodes.length () == 1
+              && is_cxa_pure_virtual_p (nodes[0]->decl))
+       nodes.pop ();
+      if (pure_virtual && nodes.length ())
+       return;
       if (!inserted->add (target))
        {
          cached_polymorphic_call_targets->add (target_node);
@@ -3328,6 +3355,9 @@ possible_polymorphic_call_target_p (tree otr_type,
           || fcode == BUILT_IN_TRAP))
     return true;
 
+  if (is_cxa_pure_virtual_p (n->decl))
+    return true;
+
   if (!odr_hash)
     return true;
   targets = possible_polymorphic_call_targets (otr_type, otr_token, ctx, &final);
index a75c88e..b0a44cd 100644 (file)
@@ -1,3 +1,8 @@
+2016-01-19  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/66223
+       * g++.dg/ipa/devirt-50.C: New testcase.
+
 2016-01-19  Marek Polacek  <polacek@redhat.com>
 
        PR c++/68965
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-50.C b/gcc/testsuite/g++.dg/ipa/devirt-50.C
new file mode 100644 (file)
index 0000000..32071cf
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized"  } */
+struct B {
+        B* self;
+        B() : self( this ) { self->f(); }
+        virtual void f() = 0;
+    };
+
+    struct D : B
+    {
+        void f() {}
+    };
+
+    int main()
+    {
+        D d;
+    }
+
+/* { dg-final { scan-tree-dump "cxa_pure_virtual" "optimized"} } */