aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/gimple-fold.c6
-rw-r--r--gcc/gimple.h2
-rw-r--r--gcc/ipa-cp.c2
-rw-r--r--gcc/ipa-prop.c2
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/torture/pr48661.C77
7 files changed, 101 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fb7509c..2c136bf 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 9047f67..a6e326b 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -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
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 3146b70..9ae29c4 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -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);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 5ec0b2c..d8de9b7 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -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)
{
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index be223cc..811884f 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7f1ff58..96fb5c5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..8de2142
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr48661.C
@@ -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;
+}