re PR middle-end/48661 (wrong-code regression with devirtualization)
authorJakub Jelinek <jakub@redhat.com>
Mon, 18 Apr 2011 21:58:51 +0000 (23:58 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 18 Apr 2011 21:58:51 +0000 (23:58 +0200)
PR middle-end/48661
* gimple-fold.c (gimple_get_virt_method_for_binfo): Return NULL
if TREE_TYPE (v) is non-NULL.

* gimple-fold.c (gimple_get_virt_method_for_binfo): Renamed from
gimple_get_virt_mehtod_for_binfo.
* gimple.h (gimple_get_virt_method_for_binfo): Likewise.
* ipa-cp.c (ipcp_process_devirtualization_opportunities): Adjust
callers.
* ipa-prop.c (try_make_edge_direct_virtual_call): Likewise.

* g++.dg/torture/pr48661.C: New test.

From-SVN: r172677

gcc/ChangeLog
gcc/gimple-fold.c
gcc/gimple.h
gcc/ipa-cp.c
gcc/ipa-prop.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr48661.C [new file with mode: 0644]

index fb7509c2537a92dc5d592b9fdc39e531a6061480..2c136bf1244cb8283f5d44ece5bcd0d1612b9d21 100644 (file)
@@ -1,3 +1,16 @@
+2011-04-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/48661
+       * gimple-fold.c (gimple_get_virt_method_for_binfo): Return NULL
+       if TREE_TYPE (v) is non-NULL.
+
+       * gimple-fold.c (gimple_get_virt_method_for_binfo): Renamed from
+       gimple_get_virt_mehtod_for_binfo.
+       * gimple.h (gimple_get_virt_method_for_binfo): Likewise.
+       * ipa-cp.c (ipcp_process_devirtualization_opportunities): Adjust
+       callers.
+       * ipa-prop.c (try_make_edge_direct_virtual_call): Likewise.
+
 2011-05-18  Michael Matz  <matz@suse.de>
            Steve Ellcey  <sje@cup.hp.com>
 
index 9047f670e7d292dd1735b5708d9e95213903dbe4..a6e326bdd1d1c9574067495e483ba6f2e355f743 100644 (file)
@@ -1372,7 +1372,7 @@ gimple_fold_builtin (gimple stmt)
    is a thunk (other than a this adjustment which is dealt with by DELTA). */
 
 tree
-gimple_get_virt_mehtod_for_binfo (HOST_WIDE_INT token, tree known_binfo,
+gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo,
                                  tree *delta, bool refuse_thunks)
 {
   HOST_WIDE_INT i;
@@ -1391,6 +1391,10 @@ gimple_get_virt_mehtod_for_binfo (HOST_WIDE_INT token, tree known_binfo,
       v = TREE_CHAIN (v);
     }
 
+  /* If BV_VCALL_INDEX is non-NULL, give up.  */
+  if (TREE_TYPE (v))
+    return NULL_TREE;
+
   fndecl = TREE_VALUE (v);
   node = cgraph_get_node_or_alias (fndecl);
   if (refuse_thunks
index 3146b70cb125bd7062ee35953f7111229eff397d..9ae29c4697df0311318dc0f3053401e8a3479e9c 100644 (file)
@@ -896,7 +896,7 @@ unsigned get_gimple_rhs_num_ops (enum tree_code);
 gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
 const char *gimple_decl_printable_name (tree, int);
 bool gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace);
-tree gimple_get_virt_mehtod_for_binfo (HOST_WIDE_INT, tree, tree *, bool);
+tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree, tree *, bool);
 void gimple_adjust_this_by_delta (gimple_stmt_iterator *, tree);
 /* Returns true iff T is a valid GIMPLE statement.  */
 extern bool is_gimple_stmt (tree);
index 5ec0b2c7acaa431ff91b698eea20a383bec3c097..d8de9b7d9e819863a8a2fa7a5ab05f812378b03a 100644 (file)
@@ -1266,7 +1266,7 @@ ipcp_process_devirtualization_opportunities (struct cgraph_node *node)
        {
          tree binfo = VEC_index (tree, info->params[param_index].types, j);
          tree d;
-         tree t = gimple_get_virt_mehtod_for_binfo (token, binfo, &d, true);
+         tree t = gimple_get_virt_method_for_binfo (token, binfo, &d, true);
 
          if (!t)
            {
index be223cc792509cc78ad02eb48709d5acea785f64..811884f1342d6e324a65f1c8039c20c6eeeb4dbe 100644 (file)
@@ -1718,7 +1718,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
   type = ie->indirect_info->otr_type;
   binfo = get_binfo_at_offset (binfo, ie->indirect_info->anc_offset, type);
   if (binfo)
-    target = gimple_get_virt_mehtod_for_binfo (token, binfo, &delta, true);
+    target = gimple_get_virt_method_for_binfo (token, binfo, &delta, true);
   else
     return NULL;
 
index 7f1ff5872e4bd8946ecfbef0f39686b383bf4f04..96fb5c5ace8814d9da1cd1e54d633fe2cc397464 100644 (file)
@@ -1,5 +1,8 @@
 2011-04-18  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/48661
+       * g++.dg/torture/pr48661.C: New test.
+
        PR c++/48632
        * g++.dg/gomp/pr48632.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/torture/pr48661.C b/gcc/testsuite/g++.dg/torture/pr48661.C
new file mode 100644 (file)
index 0000000..8de2142
--- /dev/null
@@ -0,0 +1,77 @@
+// PR middle-end/48661
+// { dg-do run }
+
+extern "C" void abort ();
+
+__attribute__((noinline))
+double
+foo (double x, double y)
+{
+  asm volatile ("" : : : "memory");
+  return x + y;
+}
+
+__attribute__((noinline, noclone))
+void
+bar (int x)
+{
+  if (x != 123)
+    abort ();
+}
+
+struct A
+{
+  double a1, a2;
+};
+
+struct B 
+{
+  virtual int m () const = 0 ;
+};
+
+struct C
+{
+  virtual ~C () {}
+};
+
+struct D : virtual public B, public C
+{ 
+  explicit D (const A &x) : d(123) { foo (x.a2, x.a1); }
+  int m () const { return d; }
+  int d;
+}; 
+
+struct E
+{
+  E () : d(0) {}
+  virtual void n (const B &x) { d = x.m (); x.m (); x.m (); }
+  int d;
+};
+
+void
+test ()
+{
+  A a;
+  a.a1 = 0;
+  a.a2 = 1;
+  E p;
+  D q (a);
+  const B &b = q;
+  bar (b.m ());
+  p.n (b);
+  bar (p.d);
+}
+
+void
+baz ()
+{
+  A a;
+  D p2 (a);
+}
+
+int
+main ()
+{
+  test ();
+  return 0;
+}