summaryrefslogtreecommitdiff
path: root/gcc/ipa-prop.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-03 00:24:52 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-03 00:24:52 +0000
commit3a4f7ef5722d3b1a35d53e9d5673d5a1a2ceccc9 (patch)
tree76bd028dd2a79384d67f52b8ff5e5cbe8b093dfa /gcc/ipa-prop.c
parent187f1b41b4e23111f94527d3f400aa7ac4aba52d (diff)
downloadgcc-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.c21
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