devirt-46.C: New testcase.
authorJan Hubicka <hubicka@ucw.cz>
Sat, 4 Oct 2014 18:29:03 +0000 (20:29 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 4 Oct 2014 18:29:03 +0000 (18:29 +0000)
* g++.dg/ipa/devirt-46.C: New testcase.
* ipa-prop.c (ipa_compute_jump_functions_for_edge): Call
get_dynamic_type; drop TODO.
* ipa-polymorphic-call.c
(ipa_polymorphic_call_context::get_dynamic_type): Be ready
for otr_type to be unknown.

From-SVN: r215890

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

index b8bc17b8699d51930a9f27e8562141ef7f0d16e7..d33827012e56822cca55e5a2e3d5d6d77ca38c25 100644 (file)
@@ -1,3 +1,11 @@
+2014-10-04  Jan Hubicka  <hubicka@ucw.cz>
+
+       * ipa-prop.c (ipa_compute_jump_functions_for_edge): Call
+       get_dynamic_type; drop TODO.
+       * ipa-polymorphic-call.c
+       (ipa_polymorphic_call_context::get_dynamic_type): Be ready
+       for otr_type to be unknown.
+
 2014-10-04  Trevor Saunders  <tsaunders@mozilla.com>
 
        * common/config/score/score-common.c: Remove.
index a9b037a5211ccc03ead3347732a615543d340484..ecbd78ce33d415a30c73bbc7c9bf5e019c86b179 100644 (file)
@@ -1390,12 +1390,13 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance,
      This is because we do not update INSTANCE when walking inwards.  */
   HOST_WIDE_INT instance_offset = offset;
 
-  otr_type = TYPE_MAIN_VARIANT (otr_type);
+  if (otr_type)
+    otr_type = TYPE_MAIN_VARIANT (otr_type);
 
   /* Walk into inner type. This may clear maybe_derived_type and save us
      from useless work.  It also makes later comparsions with static type
      easier.  */
-  if (outer_type)
+  if (outer_type && otr_type)
     {
       if (!restrict_to_inner_class (otr_type))
         return false;
@@ -1484,8 +1485,9 @@ ipa_polymorphic_call_context::get_dynamic_type (tree instance,
   /* We look for vtbl pointer read.  */
   ao.size = POINTER_SIZE;
   ao.max_size = ao.size;
-  ao.ref_alias_set
-    = get_deref_alias_set (TREE_TYPE (BINFO_VTABLE (TYPE_BINFO (otr_type))));
+  if (otr_type)
+    ao.ref_alias_set
+      = get_deref_alias_set (TREE_TYPE (BINFO_VTABLE (TYPE_BINFO (otr_type))));
 
   if (dump_file)
     {
index c5bcb3a908f5f44132b07e2b13c450ed17339642..d5ecea413039c5bce82235b93896d6ceb27eab49 100644 (file)
@@ -1898,10 +1898,11 @@ ipa_compute_jump_functions_for_edge (struct func_body_info *fbi,
       tree param_type = ipa_get_callee_param_type (cs, n);
       if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
        {
+         tree instance;
          struct ipa_polymorphic_call_context context (cs->caller->decl,
                                                       arg, cs->call_stmt,
-                                                      NULL);
-         /* TODO: We should also handle dynamic types.  */
+                                                      &instance);
+         context.get_dynamic_type (instance, arg, NULL, cs->call_stmt);
          *ipa_get_ith_polymorhic_call_context (args, n) = context;
          if (!context.useless_p ())
            useful_context = true;
index 9db549ee6d304718defd6dc264a837786ef25cb9..4672a6830f7aa631aaaf9d6765917816265eff78 100644 (file)
@@ -1,3 +1,7 @@
+2014-10-04  Jan Hubicka  <hubicka@ucw.cz>
+
+       * g++.dg/ipa/devirt-46.C: New testcase.
+
 2014-10-04  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        PR fortran/36534
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-46.C b/gcc/testsuite/g++.dg/ipa/devirt-46.C
new file mode 100644 (file)
index 0000000..a6da9c9
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-ipa-cp -fdump-ipa-inline-details -fno-early-inlining -fdump-tree-optimized" } */
+struct A {
+   virtual int foo(){return 1;}
+};
+struct B:A {
+   virtual int foo(){return 2;}
+};
+static void
+test (struct A *a)
+{
+  if (a->foo() != 2)
+   __builtin_abort ();
+}
+int
+m()
+{
+  struct A *a = new B;
+  test (a);
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a speculative target\[^\\n\]*B::foo" 1 "inline"  } } */
+/* { dg-final { scan-ipa-dump-not "OBJ_TYPE_REF" "optimized"  } } */
+/* { dg-final { scan-ipa-dump-not "abort" "optimized"  } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */
+/* { dg-final { cleanup-ipa-dump "optimized" } } */