diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 43 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/devirt1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr47382.C | 30 |
5 files changed, 43 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 24c8e91..39b8d44 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-01-25 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/47382 + * gimple-fold.c (gimple_fold_obj_type_ref_call): Removed. + (gimple_fold_call): Do not call gimple_fold_obj_type_ref_call. + 2011-01-25 Joel Sherrill <joel.sherrill@oarcorp.com> * config/m32r/m32r.c: Define TARGET_EXCEPT_UNWIND_INFO to diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 042c813..abc2273 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -1443,38 +1443,6 @@ gimple_adjust_this_by_delta (gimple_stmt_iterator *gsi, tree delta) gimple_call_set_arg (call_stmt, 0, tmp); } -/* Fold a call statement to OBJ_TYPE_REF to a direct call, if possible. GSI - determines the statement, generating new statements is allowed only if - INPLACE is false. Return true iff the statement was changed. */ - -static bool -gimple_fold_obj_type_ref_call (gimple_stmt_iterator *gsi) -{ - gimple stmt = gsi_stmt (*gsi); - tree ref = gimple_call_fn (stmt); - tree obj = OBJ_TYPE_REF_OBJECT (ref); - tree binfo, fndecl, delta; - HOST_WIDE_INT token; - - if (TREE_CODE (obj) != ADDR_EXPR) - return false; - obj = TREE_OPERAND (obj, 0); - if (!DECL_P (obj) - || TREE_CODE (TREE_TYPE (obj)) != RECORD_TYPE) - return false; - binfo = TYPE_BINFO (TREE_TYPE (obj)); - if (!binfo) - return false; - - token = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1); - fndecl = gimple_get_virt_mehtod_for_binfo (token, binfo, &delta, false); - if (!fndecl) - return false; - gcc_assert (integer_zerop (delta)); - gimple_call_set_fndecl (stmt, fndecl); - return true; -} - /* Attempt to fold a call statement referenced by the statement iterator GSI. The statement may be replaced by another statement, e.g., if the call simplifies to a constant value. Return true if any changes were made. @@ -1500,17 +1468,6 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) return true; } } - else - { - /* ??? Should perhaps do this in fold proper. However, doing it - there requires that we create a new CALL_EXPR, and that requires - copying EH region info to the new node. Easier to just do it - here where we can just smash the call operand. */ - callee = gimple_call_fn (stmt); - if (TREE_CODE (callee) == OBJ_TYPE_REF) - return gimple_fold_obj_type_ref_call (gsi); - } - return false; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9046959..b23f02d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-01-25 Martin Jambor <mjambor@suse.cz> + + PR tree-optimization/47382 + * g++.dg/torture/pr47382.C: New test. + * g++.dg/opt/devirt1.C: Xfail. + 2011-01-25 Yao Qi <yao@codesourcery.com> PR target/45701 diff --git a/gcc/testsuite/g++.dg/opt/devirt1.C b/gcc/testsuite/g++.dg/opt/devirt1.C index 617db05..0a825c2 100644 --- a/gcc/testsuite/g++.dg/opt/devirt1.C +++ b/gcc/testsuite/g++.dg/opt/devirt1.C @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-O" } -// { dg-final { scan-assembler "xyzzy" } } +// { dg-final { scan-assembler "xyzzy" { xfail *-*-* } } } struct S { S(); virtual void xyzzy(); }; inline void foo(S *s) { s->xyzzy(); } diff --git a/gcc/testsuite/g++.dg/torture/pr47382.C b/gcc/testsuite/g++.dg/torture/pr47382.C new file mode 100644 index 0000000..a12dbe3 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr47382.C @@ -0,0 +1,30 @@ +// { dg-do run } + +extern "C" void abort (); + +struct A +{ + inline ~A (); + virtual void foo () {} +}; + +struct B : A +{ + virtual void foo () { abort(); } +}; + +static inline void middleman (A *a) +{ + a->foo (); +} + +inline A::~A () +{ + middleman (this); +} + +int main () +{ + B b; + return 0; +} |