From 4c0b6eaeb39f5378777d53a432308fde1d2f8e0a Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 5 Mar 2015 00:10:29 +0000 Subject: [PATCH] PR ipa/65270 * ipa-icf.c (sem_item::compare_cgraph_references): Compare vtable references for their containing type. (sem_function::equals_wpa): Compare TYPE_RESTRICT and type attributes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221199 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/ipa-icf.c | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 72760c06723..55e212dffd5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-03-03 Jan Hubicka + + PR ipa/65270 + * ipa-icf.c (sem_item::compare_cgraph_references): Compare + vtable references for their containing type. + (sem_function::equals_wpa): Compare TYPE_RESTRICT + and type attributes. + 2015-03-04 Eric Botcazou * fold-const.c (round_up_loc): Cast divisor to signed on all paths diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index 1055c23cbc7..c55a09f7281 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -345,6 +345,20 @@ sem_item::compare_cgraph_references ( { enum availability avail1, avail2; + if (n1 == n2) + return true; + + /* Merging two definitions with a reference to equivalent vtables, but + belonging to a different type may result in ipa-polymorphic-call analysis + giving a wrong answer about the dynamic type of instance. */ + if (is_a (n1) + && (DECL_VIRTUAL_P (n1->decl) || DECL_VIRTUAL_P (n2->decl)) + && (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl) + || !types_must_be_same_for_odr (DECL_CONTEXT (n1->decl), + DECL_CONTEXT (n2->decl)))) + return return_false_with_msg + ("references to virtual tables can not be merged"); + if (address && n1->equal_address_to (n2) == 1) return true; if (!address && n1->semantically_equivalent_p (n2)) @@ -407,6 +421,10 @@ sem_function::equals_wpa (sem_item *item, m_compared_func->arg_types[i], is_not_leaf, i == 0)) return return_false_with_msg ("argument type is different"); + if (POINTER_TYPE_P (arg_types[i]) + && (TYPE_RESTRICT (arg_types[i]) + != TYPE_RESTRICT (m_compared_func->arg_types[i]))) + return return_false_with_msg ("argument restrict flag mismatch"); } /* Result type checking. */ @@ -417,6 +435,10 @@ sem_function::equals_wpa (sem_item *item, if (node->num_references () != item->node->num_references ()) return return_false_with_msg ("different number of references"); + if (comp_type_attributes (TREE_TYPE (decl), + TREE_TYPE (item->decl)) != 1) + return return_false_with_msg ("different type attributes"); + ipa_ref *ref = NULL, *ref2 = NULL; for (unsigned i = 0; node->iterate_reference (i, ref); i++) { -- 2.11.4.GIT