From: Jakub Jelinek Date: Mon, 18 Apr 2011 21:58:51 +0000 (+0200) Subject: re PR middle-end/48661 (wrong-code regression with devirtualization) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=848257079a98c2fa9c7d5a8cc666f7c0798e5ec0;p=gcc.git re PR middle-end/48661 (wrong-code regression with devirtualization) 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fb7509c2537..2c136bf1244 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2011-04-18 Jakub Jelinek + + 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 Steve Ellcey diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 9047f670e7d..a6e326bdd1d 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 3146b70cb12..9ae29c4697d 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 5ec0b2c7aca..d8de9b7d9e8 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 be223cc7925..811884f1342 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 7f1ff5872e4..96fb5c5ace8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2011-04-18 Jakub Jelinek + 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 00000000000..8de2142f737 --- /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; +}