diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2015-04-12 03:08:04 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2015-04-12 01:08:04 +0000 |
commit | 523f0450d78fc40d5231503f4ad4cc5f6bdf8139 (patch) | |
tree | 7e5a1a4540aca33ee526f54f87dd5638bdcd70fe | |
parent | 1dcdafb2e61f1e0d98e50e2fbf5ee00e2893160a (diff) | |
download | gcc-523f0450d78fc40d5231503f4ad4cc5f6bdf8139.zip gcc-523f0450d78fc40d5231503f4ad4cc5f6bdf8139.tar.gz gcc-523f0450d78fc40d5231503f4ad4cc5f6bdf8139.tar.bz2 |
Jan Hubicka <hubicka@ucw.cz>
Martin Liska <mliska@suse.cz>
PR ipa/65722
* g++.dg/ipa/pr65722.C: New testcase.
* ipa-icf.c (sem_item::compare_cgraph_references): function and
variable can not match.
(sem_item::update_hash_by_addr_refs): Fix handling of virtual tables.
(sem_variable::equals_wpa): Fix checking of DECL_FINAL_P patch.
Co-Authored-By: Martin Liska <mliska@suse.cz>
From-SVN: r222015
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/ipa-icf.c | 33 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/pr65722.C | 21 |
4 files changed, 54 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ce59ef8..19350f3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-04-11 Jan Hubicka <hubicka@ucw.cz> + Martin Liska <mliska@suse.cz> + + PR ipa/65722 + * ipa-icf.c (sem_item::compare_cgraph_references): function and + variable can not match. + (sem_item::update_hash_by_addr_refs): Fix handling of virtual tables. + (sem_variable::equals_wpa): Fix checking of DECL_FINAL_P patch. + 2015-04-11 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/65735 diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index 8f8a0cf..bdce9cd 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -368,6 +368,10 @@ sem_item::compare_cgraph_references ( if (n1 == n2) return true; + /* Never match variable and function. */ + if (is_a <varpool_node *> (n1) != is_a <varpool_node *> (n2)) + return false; + /* 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. */ @@ -587,9 +591,6 @@ void sem_item::update_hash_by_addr_refs (hash_map <symtab_node *, sem_item *> &m_symtab_node_map) { - if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl)) - return; - ipa_ref* ref; inchash::hash hstate (hash); for (unsigned i = 0; i < node->num_references (); i++) @@ -627,7 +628,7 @@ sem_item::update_hash_by_local_refs (hash_map <symtab_node *, ref = node->iterate_reference (j, ref); sem_item **result = m_symtab_node_map.get (ref->referring); if (result) - state.merge_hash ((*result)->hash); + state.add_int (ref->referring->type); } if (type == FUNC) @@ -1667,17 +1668,19 @@ sem_variable::equals_wpa (sem_item *item, ref->address_matters_p ())) return false; - /* DECL_FINAL_P flag on methods referred by virtual tables is used - to decide on completeness possible_polymorphic_call_targets lists - and therefore it must match. */ - if ((DECL_VIRTUAL_P (decl) || DECL_VIRTUAL_P (item->decl)) - && (DECL_VIRTUAL_P (ref->referred->decl) - || DECL_VIRTUAL_P (ref2->referred->decl)) - && ((DECL_VIRTUAL_P (ref->referred->decl) - != DECL_VIRTUAL_P (ref2->referred->decl)) - || (DECL_FINAL_P (ref->referred->decl) - != DECL_FINAL_P (ref2->referred->decl)))) - return return_false_with_msg ("virtual or final flag mismatch"); + /* When matching virtual tables, be sure to also match information + relevant for polymorphic call analysis. */ + if (DECL_VIRTUAL_P (decl) || DECL_VIRTUAL_P (item->decl)) + { + if (DECL_VIRTUAL_P (ref->referred->decl) + != DECL_VIRTUAL_P (ref2->referred->decl)) + return return_false_with_msg ("virtual flag mismatch"); + if (DECL_VIRTUAL_P (ref->referred->decl) + && is_a <cgraph_node *> (ref->referred) + && (DECL_FINAL_P (ref->referred->decl) + != DECL_FINAL_P (ref2->referred->decl))) + return return_false_with_msg ("final flag mismatch"); + } } return true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 75c3b44..401bf14 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-04-11 Jan Hubicka <hubicka@ucw.cz> + Martin Liska <mliska@suse.cz> + + PR ipa/65722 + * g++.dg/ipa/pr65722.C: New testcase. + 2015-04-11 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/65735 diff --git a/gcc/testsuite/g++.dg/ipa/pr65722.C b/gcc/testsuite/g++.dg/ipa/pr65722.C new file mode 100644 index 0000000..ee4ea24 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr65722.C @@ -0,0 +1,21 @@ +// { dg-do compile } +// { dg-options "-O -fipa-icf -fno-rtti" } + +struct A +{ + virtual void f () + { + __builtin_abort (); + } + virtual void g (); +}; + +struct B : virtual A { }; +struct C : B, virtual A { }; + +void foo() +{ + C c; + C *p = &c; + p->f (); +} |