re PR ipa/65270 (issues with merging memory accesses from different code paths)
authorJan Hubicka <hubicka@ucw.cz>
Thu, 5 Mar 2015 00:10:29 +0000 (01:10 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 5 Mar 2015 00:10:29 +0000 (00:10 +0000)
  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.

From-SVN: r221199

gcc/ChangeLog
gcc/ipa-icf.c

index 72760c0672333e4e55720770f3e2d1a420ad57fe..55e212dffd5b629c90e16a44c3fc54b6d318e1b4 100644 (file)
@@ -1,3 +1,11 @@
+2015-03-03  Jan Hubicka  <hubicka@ucw.cz>
+
+       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  <ebotcazou@adacore.com>
 
        * fold-const.c (round_up_loc): Cast divisor to signed on all paths
index 1055c23cbc708fdc02ac1330d4606fe7cd822a29..c55a09f72810a0a9fffa6c9ad7a5dc37abcd3482 100644 (file)
@@ -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 <varpool_node *> (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++)
     {