aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-04-12 03:08:04 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2015-04-12 01:08:04 +0000
commit523f0450d78fc40d5231503f4ad4cc5f6bdf8139 (patch)
tree7e5a1a4540aca33ee526f54f87dd5638bdcd70fe
parent1dcdafb2e61f1e0d98e50e2fbf5ee00e2893160a (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/ipa-icf.c33
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr65722.C21
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 ();
+}