> 
> commit f075b8c5adcf9cb6336563c472c8d624c54184db
> Author: Jan Hubicka <hubi...@ucw.cz>
> Date:   Thu Aug 26 15:33:56 2021 +0200
> 
>     Fix off-by-one error in try_merge_with
> 
>     gcc/ChangeLog:
> 
>             * ipa-modref-tree.h (modref_ref_node::verify): New member
>             functoin.
>             (modref_ref_node::insert): Use it.
>             (modref_ref_node::try_mere_with): Fix off by one error.
> 
> caused libgo build failure on Linux/i686:
Sorry for that.  Jeff sent me independent testcase and it seems to be
same problem.  It turns out that after merging two access ranges one
needs to restart the walk since after this earlier access ranges may
merge or be contained in the bigger range produced. I missed this case
and apologize for it.

        * ipa-modref-tree.h (modref_access_node::try_merge_with): Restart
        search after merging.
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index 97934a91ada..fc55583e571 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -405,20 +411,35 @@ private:
   void
   try_merge_with (size_t index)
   {
-    modref_access_node *a2;
     size_t i;
 
-    FOR_EACH_VEC_SAFE_ELT (accesses, i, a2)
-      if (i != index
-         && ((*accesses)[index].contains (*a2)
-             || (*accesses)[index].merge (*a2, false)))
+    for (i = 0; i < accesses->length ();)
+      if (i != index)
        {
-         accesses->unordered_remove (i);
-         if (index == accesses->length ())
-           index = i;
+         bool found = false, restart = false;
+         modref_access_node *a = &(*accesses)[i];
+         modref_access_node *n = &(*accesses)[index];
+
+         if (n->contains (*a))
+           found = true;
+         if (!found && n->merge (*a, false))
+           found = restart = true;
+         if (found)
+           {
+             accesses->unordered_remove (i);
+             if (index == accesses->length ())
+               {
+                 index = i;
+                 i++;
+               }
+             if (restart)
+               i = 0;
+           }
          else
-           i--;
+           i++;
        }
+      else
+       i++;
   }
 };
 

Reply via email to