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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-05-02
                 CC|                            |hubicka at gcc dot gnu.org
          Component|c++                         |tree-optimization
     Ever confirmed|0                           |1

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
This comes from build_type_attribute_qual_variant:
1159          if (ntype != dtype)
1160            /* This variant was already in the hash table, don't mess with
1161               TYPE_CANONICAL.  */;
1162          else if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
1163                   || !comp_type_attributes (ntype, ttype))
1164            /* If the target-dependent attributes make NTYPE different from
1165               its canonical type, we will need to use structural equality
1166               checks for this type.
1167    
1168               We shouldn't get here for stripping attributes from a type;
1169               the no-attribute type might not need structural comparison. 
But
1170               we can if was discarded from type_hash_table.  */
1171            SET_TYPE_STRUCTURAL_EQUALITY (ntype);
1172          else if (TYPE_CANONICAL (ntype) == ntype)
1173            TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
for the FUNCTION_TYPE, so the fntype has NULL TYPE_CANONICAL and then:
9558              if (comp_template_args (CLASSTYPE_TI_ARGS (template_type),
arglist))
9559                /* This instantiation is another name for the primary
9560                   template type. Set the TYPE_CANONICAL field
9561                   appropriately. */
9562                TYPE_CANONICAL (t) = template_type;
9563              else if (any_template_arguments_need_structural_equality_p
(arglist))
9564                /* Some of the template arguments require structural
9565                   equality testing, so this template class requires
9566                   structural equality testing. */
9567                SET_TYPE_STRUCTURAL_EQUALITY (t);
because any_template_arguments_need_structural_equality_p is true, we keep
TYPE_CANONICAL cleared.

The following patch fixes the ICE for me, but am not sure if it is 100%
correct.  I don't see other parts in the middle-end that would not accept types
with NULL TYPE_CANONICAL, they sometimes punt, or do more careful comparison,
but don't just ICE.

--- gcc/ipa-devirt.c.jj 2019-04-15 19:45:28.796340266 +0200
+++ gcc/ipa-devirt.c    2019-05-02 10:46:03.077896176 +0200
@@ -2020,7 +2020,7 @@ obj_type_ref_class (const_tree ref)
   ref = TREE_VALUE (TYPE_ARG_TYPES (ref));
   gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
   tree ret = TREE_TYPE (ref);
-  if (!in_lto_p)
+  if (!in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (ret))
     ret = TYPE_CANONICAL (ret);
   else
     ret = get_odr_type (ret)->type;
@@ -2042,7 +2042,7 @@ get_odr_type (tree type, bool insert)
   int base_id = -1;

   type = TYPE_MAIN_VARIANT (type);
-  if (!in_lto_p)
+  if (!in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (type))
     type = TYPE_CANONICAL (type);

   gcc_checking_assert (can_be_name_hashed_p (type)

Reply via email to