Jan Hubicka <hubicka@ucw.cz>
authorJan Hubicka <hubicka@ucw.cz>
Sun, 12 Apr 2015 01:08:04 +0000 (03:08 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 12 Apr 2015 01:08:04 +0000 (01:08 +0000)
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

gcc/ChangeLog
gcc/ipa-icf.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr65722.C [new file with mode: 0644]

index ce59ef8087b61274ba6a97e2f20cc60dd32f0ff3..19350f358944c7554a91357a750c99d17713b389 100644 (file)
@@ -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
index 8f8a0cf34636d57188bc52242fd98241ad3ea9a8..bdce9cd26614ac33b91d411e0b541fe64369a4a4 100644 (file)
@@ -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;
index 75c3b44cf26c72bc0a1c9e3b4954d20d0f1af56e..401bf14cc55385334f9fa07ffb0bc523768bf8c0 100644 (file)
@@ -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 (file)
index 0000000..ee4ea24
--- /dev/null
@@ -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 ();
+}