https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83983

--- Comment #5 from Eric Botcazou <ebotcazou at gcc dot gnu.org> ---
> I think it may be a bug in the odr hash function with an accidental
> hash collision but I am not sure.

The ODR hash function essentially hashes the name only here so the collision is
apparently by design.  The discrepancy between x86 and ARM/SPARC comes from:

  /* For ODR types be sure to compare their names.
     To support -wno-odr-type-merging we allow one type to be non-ODR
     and other ODR even though it is a violation.  */
  if (types_odr_comparable (t1, t2, true))
    {
      if (!types_same_for_odr (t1, t2, true))
        return false;
      /* Limit recursion: If subtypes are ODR types and we know
         that they are same, be happy.  */
      if (!odr_type_p (t1) || !get_odr_type (t1, true)->odr_violated)
        return true;
    }

The call to get_odr_type (t1, true) is supposed to yield the warning, but this
depends on the order in which types t1 and t2 have been inserted in the table.

In other words, get_odr_type (t1, true) works on x86 and get_odr_type (t2,
true) works on ARM/SPARC, so maybe something like:

Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c        (revision 258068)
+++ ipa-devirt.c        (working copy)
@@ -686,7 +686,10 @@ odr_subtypes_equivalent_p (tree t1, tree t2,
         return false;
       /* Limit recursion: If subtypes are ODR types and we know
          that they are same, be happy.  */
-      if (!odr_type_p (t1) || !get_odr_type (t1, true)->odr_violated)
+      if (!odr_type_p (t1)
+         || !odr_type_p (t2)
+         || (!get_odr_type (t1, true)->odr_violated
+             && !get_odr_type (t2, true)->odr_violated))
         return true;
     }

is the proper thing to do.

Reply via email to