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
This commit is contained in:
parent
1dcdafb2e6
commit
523f0450d7
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
21
gcc/testsuite/g++.dg/ipa/pr65722.C
Normal file
21
gcc/testsuite/g++.dg/ipa/pr65722.C
Normal file
@ -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 ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user