diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-03 00:24:52 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-02-03 00:24:52 +0000 |
commit | 3a4f7ef5722d3b1a35d53e9d5673d5a1a2ceccc9 (patch) | |
tree | 76bd028dd2a79384d67f52b8ff5e5cbe8b093dfa /gcc/ipa-prop.c | |
parent | 187f1b41b4e23111f94527d3f400aa7ac4aba52d (diff) | |
download | gcc-3a4f7ef5722d3b1a35d53e9d5673d5a1a2ceccc9.tar.gz |
* ipa-devirt.c (subbinfo_with_vtable_at_offset,
vtable_pointer_value_to_binfo): New functions.
* ipa-utils.h (vtable_pointer_value_to_binfo): Declare.
* ipa-prop.c (extr_type_from_vtbl_ptr_store): Use it.
* g++.dg/ipa/devirt-23.C: New testcase.
* g++.dg/ipa/devirt-20.C: Fix template.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207413 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-prop.c')
-rw-r--r-- | gcc/ipa-prop.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index f8a1ca4f3d4..3024414ab8a 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -591,7 +591,7 @@ static tree extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci) { HOST_WIDE_INT offset, size, max_size; - tree lhs, rhs, base; + tree lhs, rhs, base, binfo; if (!gimple_assign_single_p (stmt)) return NULL_TREE; @@ -599,13 +599,7 @@ extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci) lhs = gimple_assign_lhs (stmt); rhs = gimple_assign_rhs1 (stmt); if (TREE_CODE (lhs) != COMPONENT_REF - || !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)) - || TREE_CODE (rhs) != ADDR_EXPR) - return NULL_TREE; - rhs = get_base_address (TREE_OPERAND (rhs, 0)); - if (!rhs - || TREE_CODE (rhs) != VAR_DECL - || !DECL_VIRTUAL_P (rhs)) + || !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1))) return NULL_TREE; base = get_ref_base_and_extent (lhs, &offset, &size, &max_size); @@ -624,7 +618,16 @@ extr_type_from_vtbl_ptr_store (gimple stmt, struct type_change_info *tci) else if (tci->object != base) return NULL_TREE; - return DECL_CONTEXT (rhs); + binfo = vtable_pointer_value_to_binfo (rhs); + + /* FIXME: vtable_pointer_value_to_binfo may return BINFO of a + base of outer type. In this case we would need to either + work on binfos or translate it back to outer type and offset. + KNOWN_TYPE jump functions are not ready for that, yet. */ + if (!binfo || TYPE_BINFO (BINFO_TYPE (binfo)) != binfo) + return NULL; + + return BINFO_TYPE (binfo); } /* Callback of walk_aliased_vdefs and a helper function for |