ipa-devirt.c (warn_odr): Make static.
authorJan Hubicka <jh@suse.cz>
Fri, 26 Oct 2018 07:20:01 +0000 (09:20 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 26 Oct 2018 07:20:01 +0000 (07:20 +0000)
* ipa-devirt.c (warn_odr): Make static.
(types_same_for_odr): Drop strict variant.
(types_odr_comparable): Likewise.
(odr_or_derived_type_p): Look for main variants.
(odr_name_hasher::equal): Cleanup comment.
(odr_subtypes_equivalent): Add warn and warned arguments; check main
variants.
(type_variants_equivalent_p): break out from ...
(odr_types_equivalent): ... here; go for main variants where needed.
(warn_odr): ... here; turn static.
(warn_types_mismatch): Compare mangled names of main variants.
* ipa-utils.h (types_odr_comparable): Drop strict parameter.
(type_with_linkage_p): Sanity check that we look at main variant.
* lto.c (lto_read_decls): Only consider main variant to be ODR type.
* tree.h (types_same_for_odr): Drop strict argument.

From-SVN: r265519

gcc/ChangeLog
gcc/ipa-devirt.c
gcc/ipa-utils.h
gcc/lto/lto.c
gcc/tree.h

index 46524ee4d519b07684d78532cc5e649b11005df9..87e79471af8e6c33b02d3fb62d749c53a6f72cf0 100644 (file)
@@ -1,3 +1,21 @@
+2018-10-26  Jan Hubicka  <jh@suse.cz>
+
+       * ipa-devirt.c (warn_odr): Make static.
+       (types_same_for_odr): Drop strict variant.
+       (types_odr_comparable): Likewise.
+       (odr_or_derived_type_p): Look for main variants.
+       (odr_name_hasher::equal): Cleanup comment.
+       (odr_subtypes_equivalent): Add warn and warned arguments; check main
+       variants.
+       (type_variants_equivalent_p): break out from ...
+       (odr_types_equivalent): ... here; go for main variants where needed.
+       (warn_odr): ... here; turn static.
+       (warn_types_mismatch): Compare mangled names of main variants.
+       * ipa-utils.h (types_odr_comparable): Drop strict parameter.
+       (type_with_linkage_p): Sanity check that we look at main variant.
+       * lto.c (lto_read_decls): Only consider main variant to be ODR type.
+       * tree.h (types_same_for_odr): Drop strict argument.
+
 2018-10-26  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/87746
index 0c6e76a65fe42da6d887ccc0df518c2784f077db..df880fe4145cced2c98e6c92ed752b1c182ab277 100644 (file)
@@ -175,6 +175,8 @@ struct default_hash_traits <type_pair>
 static bool odr_types_equivalent_p (tree, tree, bool, bool *,
                                    hash_set<type_pair> *,
                                    location_t, location_t);
+static void warn_odr (tree t1, tree t2, tree st1, tree st2,
+                     bool warn, bool *warned, const char *reason);
 
 static bool odr_violation_reported = false;
 
@@ -381,22 +383,15 @@ odr_vtable_hasher::hash (const odr_type_d *odr_type)
 
    Until we start streaming mangled type names, this function works
    only for polymorphic types.
-
-   When STRICT is true, we compare types by their names for purposes of
-   ODR violation warnings.  When strict is false, we consider variants
-   equivalent, because it is all that matters for devirtualization machinery.
 */
 
 bool
-types_same_for_odr (const_tree type1, const_tree type2, bool strict)
+types_same_for_odr (const_tree type1, const_tree type2)
 {
   gcc_checking_assert (TYPE_P (type1) && TYPE_P (type2));
 
-  if (!strict)
-    {
-      type1 = TYPE_MAIN_VARIANT (type1);
-      type2 = TYPE_MAIN_VARIANT (type2);
-    }
+  type1 = TYPE_MAIN_VARIANT (type1);
+  type2 = TYPE_MAIN_VARIANT (type2);
 
   if (type1 == type2)
     return true;
@@ -470,17 +465,15 @@ types_same_for_odr (const_tree type1, const_tree type2, bool strict)
 /* Return true if we can decide on ODR equivalency.
 
    In non-LTO it is always decide, in LTO however it depends in the type has
-   ODR info attached.
-
-   When STRICT is false, compare main variants.  */
+   ODR info attached. */
 
 bool
-types_odr_comparable (tree t1, tree t2, bool strict)
+types_odr_comparable (tree t1, tree t2)
 {
   return (!in_lto_p
-         || t1 == t2
-         || (!strict && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
-         || (odr_type_p (t1) && odr_type_p (t2))
+         || TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)
+         || (odr_type_p (TYPE_MAIN_VARIANT (t1))
+             && odr_type_p (TYPE_MAIN_VARIANT (t2)))
          || (TREE_CODE (t1) == RECORD_TYPE && TREE_CODE (t2) == RECORD_TYPE
              && TYPE_BINFO (t1) && TYPE_BINFO (t2)
              && polymorphic_type_binfo_p (TYPE_BINFO (t1))
@@ -525,7 +518,7 @@ odr_or_derived_type_p (const_tree t)
 {
   do
     {
-      if (odr_type_p (t))
+      if (odr_type_p (TYPE_MAIN_VARIANT (t)))
        return true;
       /* Function type is a tricky one. Basically we can consider it
         ODR derived if return type or any of the parameters is.
@@ -540,7 +533,7 @@ odr_or_derived_type_p (const_tree t)
             if (TREE_TYPE (t) && odr_or_derived_type_p (TREE_TYPE (t)))
               return true;
             for (t = TYPE_ARG_TYPES (t); t; t = TREE_CHAIN (t))
-              if (odr_or_derived_type_p (TREE_VALUE (t)))
+              if (odr_or_derived_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (t))))
                 return true;
             return false;
           }
@@ -566,8 +559,7 @@ odr_name_hasher::equal (const odr_type_d *o1, const tree_node *t2)
     return true;
   if (!in_lto_p)
     return false;
-  /* Check for anonymous namespaces. Those have !TREE_PUBLIC
-     on the corresponding TYPE_STUB_DECL.  */
+  /* Check for anonymous namespaces.  */
   if ((type_with_linkage_p (t1) && type_in_anonymous_namespace_p (t1))
       || (type_with_linkage_p (t2) && type_in_anonymous_namespace_p (t2)))
     return false;
@@ -639,10 +631,45 @@ set_type_binfo (tree type, tree binfo)
       gcc_assert (!TYPE_BINFO (type));
 }
 
+/* Return true if type variants match.
+   This assumes that we already verified that T1 and T2 are variants of the
+   same type.  */
+
+static bool
+type_variants_equivalent_p (tree t1, tree t2, bool warn, bool *warned)
+{
+  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
+    {
+      warn_odr (t1, t2, NULL, NULL, warn, warned,
+               G_("a type with different qualifiers is defined in another "
+                  "translation unit"));
+      return false;
+    }
+
+  if (comp_type_attributes (t1, t2) != 1)
+    {
+      warn_odr (t1, t2, NULL, NULL, warn, warned,
+               G_("a type with different attributes "
+                  "is defined in another translation unit"));
+      return false;
+    }
+
+  if (COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2)
+      && TYPE_ALIGN (t1) != TYPE_ALIGN (t2))
+    {
+      warn_odr (t1, t2, NULL, NULL, warn, warned,
+               G_("a type with different alignment "
+                  "is defined in another translation unit"));
+      return false;
+    }
+
+  return true;
+}
+
 /* Compare T1 and T2 based on name or structure.  */
 
 static bool
-odr_subtypes_equivalent_p (tree t1, tree t2,
+odr_subtypes_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
                           hash_set<type_pair> *visited,
                           location_t loc1, location_t loc2)
 {
@@ -654,20 +681,25 @@ odr_subtypes_equivalent_p (tree t1, tree t2,
     return true;
 
   /* Anonymous namespace types must match exactly.  */
-  if ((type_with_linkage_p (t1) && type_in_anonymous_namespace_p (t1))
-      || (type_with_linkage_p (t2) && type_in_anonymous_namespace_p (t2)))
+  if ((type_with_linkage_p (TYPE_MAIN_VARIANT (t1))
+       && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1)))
+      || (type_with_linkage_p (TYPE_MAIN_VARIANT (t2))
+         && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t2))))
     return false;
 
   /* 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_odr_comparable (t1, t2))
     {
-      if (!types_same_for_odr (t1, t2, true))
+      if (!types_same_for_odr (t1, t2))
         return false;
+      if (!type_variants_equivalent_p (t1, t2, warn, warned))
+       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 (TYPE_MAIN_VARIANT (t1))
+         || !get_odr_type (TYPE_MAIN_VARIANT (t1), true)->odr_violated)
         return true;
     }
 
@@ -679,15 +711,19 @@ odr_subtypes_equivalent_p (tree t1, tree t2,
       && (TYPE_NAME (t1) == NULL_TREE) != (TYPE_NAME (t2) == NULL_TREE))
     return false;
 
-  type_pair pair={t1,t2};
-  if (TYPE_UID (t1) > TYPE_UID (t2))
+  type_pair pair={TYPE_MAIN_VARIANT (t1), TYPE_MAIN_VARIANT (t2)};
+  if (TYPE_UID (TYPE_MAIN_VARIANT (t1)) > TYPE_UID (TYPE_MAIN_VARIANT (t2)))
     {
-      pair.first = t2;
-      pair.second = t1;
+      pair.first = TYPE_MAIN_VARIANT (t2);
+      pair.second = TYPE_MAIN_VARIANT (t1);
     }
   if (visited->add (pair))
     return true;
-  return odr_types_equivalent_p (t1, t2, false, NULL, visited, loc1, loc2);
+  if (odr_types_equivalent_p (TYPE_MAIN_VARIANT (t1), TYPE_MAIN_VARIANT (t2),
+                             false, NULL, visited, loc1, loc2)
+      && !type_variants_equivalent_p (t1, t2, warn, warned))
+    return false;
+  return true;
 }
 
 /* Return true if DECL1 and DECL2 are identical methods.  Consider
@@ -959,7 +995,7 @@ compare_virtual_tables (varpool_node *prevailing, varpool_node *vtable)
    If WARN is false, do nothing. Set WARNED if warning was indeed
    output.  */
 
-void
+static void
 warn_odr (tree t1, tree t2, tree st1, tree st2,
          bool warn, bool *warned, const char *reason)
 {
@@ -1083,10 +1119,13 @@ warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2)
 
   /* It is a quite common bug to reference anonymous namespace type in
      non-anonymous namespace class.  */
-  if ((type_with_linkage_p (t1) && type_in_anonymous_namespace_p (t1))
-      || (type_with_linkage_p (t2) && type_in_anonymous_namespace_p (t2)))
+  if ((type_with_linkage_p (TYPE_MAIN_VARIANT (t1))
+       && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1)))
+      || (type_with_linkage_p (TYPE_MAIN_VARIANT (t2))
+         && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t2))))
     {
-      if (type_with_linkage_p (t1) && !type_in_anonymous_namespace_p (t1))
+      if (type_with_linkage_p (TYPE_MAIN_VARIANT (t1))
+         && !type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1)))
        {
          std::swap (t1, t2);
          std::swap (loc_t1, loc_t2);
@@ -1094,10 +1133,15 @@ warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2)
       gcc_assert (TYPE_NAME (t1) && TYPE_NAME (t2)
                  && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL
                  && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL);
+      tree n1 = TYPE_NAME (t1);
+      tree n2 = TYPE_NAME (t2);
+      if (TREE_CODE (n1) == TYPE_DECL)
+       n1 = DECL_NAME (n1);
+      if (TREE_CODE (n2) == TYPE_DECL)
+       n1 = DECL_NAME (n2);
       /* Most of the time, the type names will match, do not be unnecesarily
          verbose.  */
-      if (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t1)))
-         != IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t2))))
+      if (IDENTIFIER_POINTER (n1) != IDENTIFIER_POINTER (n2))
         inform (loc_t1,
                "type %qT defined in anonymous namespace can not match "
                "type %qT across the translation unit boundary",
@@ -1112,22 +1156,24 @@ warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2)
                "the incompatible type defined in another translation unit");
       return;
     }
+  tree mt1 = TYPE_MAIN_VARIANT (t1);
+  tree mt2 = TYPE_MAIN_VARIANT (t2);
   /* If types have mangled ODR names and they are different, it is most
      informative to output those.
      This also covers types defined in different namespaces.  */
-  if (TYPE_NAME (t1) && TYPE_NAME (t2)
-      && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL
-      && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL
-      && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t1))
-      && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t2))
-      && DECL_ASSEMBLER_NAME (TYPE_NAME (t1))
-        != DECL_ASSEMBLER_NAME (TYPE_NAME (t2)))
+  if (TYPE_NAME (mt1) && TYPE_NAME (mt2)
+      && TREE_CODE (TYPE_NAME (mt1)) == TYPE_DECL
+      && TREE_CODE (TYPE_NAME (mt2)) == TYPE_DECL
+      && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (mt1))
+      && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (mt2))
+      && DECL_ASSEMBLER_NAME (TYPE_NAME (mt1))
+        != DECL_ASSEMBLER_NAME (TYPE_NAME (mt2)))
     {
       char *name1 = xstrdup (cplus_demangle
-        (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (t1))),
+        (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (mt1))),
          DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES));
       char *name2 = cplus_demangle
-        (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (t2))),
+        (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (mt2))),
          DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES);
       if (name1 && name2 && strcmp (name1, name2))
        {
@@ -1216,8 +1262,8 @@ warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2)
       return;
     }
 
-  if (types_odr_comparable (t1, t2, true)
-      && types_same_for_odr (t1, t2, true))
+  if (types_odr_comparable (t1, t2)
+      && types_same_for_odr (t1, t2))
     inform (loc_t1,
            "type %qT itself violates the C++ One Definition Rule", t1);
   /* Prevent pointless warnings like "struct aa" should match "struct aa".  */
@@ -1246,8 +1292,10 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
   /* Check first for the obvious case of pointer identity.  */
   if (t1 == t2)
     return true;
-  gcc_assert (!type_with_linkage_p (t1) || !type_in_anonymous_namespace_p (t1));
-  gcc_assert (!type_with_linkage_p (t2) || !type_in_anonymous_namespace_p (t2));
+  gcc_assert (!type_with_linkage_p (TYPE_MAIN_VARIANT (t1))
+             || !type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1)));
+  gcc_assert (!type_with_linkage_p (TYPE_MAIN_VARIANT (t2))
+             || !type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t2)));
 
   /* Can't be the same type if the types don't have the same code.  */
   if (TREE_CODE (t1) != TREE_CODE (t2))
@@ -1257,16 +1305,10 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
       return false;
     }
 
-  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
-    {
-      warn_odr (t1, t2, NULL, NULL, warn, warned,
-               G_("a type with different qualifiers is defined in another "
-                  "translation unit"));
-      return false;
-    }
-
-  if ((type_with_linkage_p (t1) && type_in_anonymous_namespace_p (t1))
-      || (type_with_linkage_p (t2) && type_in_anonymous_namespace_p (t2)))
+  if ((type_with_linkage_p (TYPE_MAIN_VARIANT (t1))
+       && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1)))
+      || (type_with_linkage_p (TYPE_MAIN_VARIANT (t2))
+         && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t2))))
     {
       /* We can not trip this when comparing ODR types, only when trying to
         match different ODR derivations from different declarations.
@@ -1275,14 +1317,6 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
       return false;
     }
 
-  if (comp_type_attributes (t1, t2) != 1)
-    {
-      warn_odr (t1, t2, NULL, NULL, warn, warned,
-               G_("a type with different attributes "
-                  "is defined in another translation unit"));
-      return false;
-    }
-
   if (TREE_CODE (t1) == ENUMERAL_TYPE
       && TYPE_VALUES (t1) && TYPE_VALUES (t2))
     {
@@ -1366,7 +1400,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
            }
 
          if (!odr_subtypes_equivalent_p (TREE_TYPE (t1), TREE_TYPE (t2),
-                                         visited, loc1, loc2))
+                                         warn, warned, visited, loc1, loc2))
            {
              warn_odr (t1, t2, NULL, NULL, warn, warned,
                        G_("it is defined as a pointer to different type "
@@ -1380,6 +1414,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
 
       if ((TREE_CODE (t1) == VECTOR_TYPE || TREE_CODE (t1) == COMPLEX_TYPE)
          && !odr_subtypes_equivalent_p (TREE_TYPE (t1), TREE_TYPE (t2),
+                                        warn, warned,
                                         visited, loc1, loc2))
        {
          /* Probably specific enough.  */
@@ -1399,7 +1434,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
        /* Array types are the same if the element types are the same and
           the number of elements are the same.  */
        if (!odr_subtypes_equivalent_p (TREE_TYPE (t1), TREE_TYPE (t2),
-                                       visited, loc1, loc2))
+                                       warn, warned, visited, loc1, loc2))
          {
            warn_odr (t1, t2, NULL, NULL, warn, warned,
                      G_("a different type is defined in another "
@@ -1417,7 +1452,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
        /* For an incomplete external array, the type domain can be
           NULL_TREE.  Check this condition also.  */
        if (i1 == NULL_TREE || i2 == NULL_TREE)
-         return true;
+          return type_variants_equivalent_p (t1, t2, warn, warned);
 
        tree min1 = TYPE_MIN_VALUE (i1);
        tree min2 = TYPE_MIN_VALUE (i2);
@@ -1441,7 +1476,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
       /* Function types are the same if the return type and arguments types
         are the same.  */
       if (!odr_subtypes_equivalent_p (TREE_TYPE (t1), TREE_TYPE (t2),
-                                     visited, loc1, loc2))
+                                     warn, warned, visited, loc1, loc2))
        {
          warn_odr (t1, t2, NULL, NULL, warn, warned,
                    G_("has different return value "
@@ -1453,7 +1488,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
 
       if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2)
          || !prototype_p (t1) || !prototype_p (t2))
-       return true;
+        return type_variants_equivalent_p (t1, t2, warn, warned);
       else
        {
          tree parms1, parms2;
@@ -1463,8 +1498,8 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
               parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
            {
              if (!odr_subtypes_equivalent_p
-                    (TREE_VALUE (parms1), TREE_VALUE (parms2), visited,
-                     loc1, loc2))
+                    (TREE_VALUE (parms1), TREE_VALUE (parms2), warn, warned,
+                     visited, loc1, loc2))
                {
                  warn_odr (t1, t2, NULL, NULL, warn, warned,
                            G_("has different parameters in another "
@@ -1484,7 +1519,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
              return false;
            }
 
-         return true;
+          return type_variants_equivalent_p (t1, t2, warn, warned);
        }
 
     case RECORD_TYPE:
@@ -1544,8 +1579,8 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
                    return false;
                  }
                if (!odr_subtypes_equivalent_p (TREE_TYPE (f1),
-                                               TREE_TYPE (f2), visited,
-                                               loc1, loc2))
+                                               TREE_TYPE (f2), warn, warned,
+                                               visited, loc1, loc2))
                  {
                    /* Do not warn about artificial fields and just go into
                       generic field mismatch warning.  */
@@ -1622,18 +1657,11 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
                   "is defined in another translation unit"));
       return false;
     }
-  if (COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2)
-      && TYPE_ALIGN (t1) != TYPE_ALIGN (t2))
-    {
-      warn_odr (t1, t2, NULL, NULL, warn, warned,
-               G_("a type with different alignment "
-                  "is defined in another translation unit"));
-      return false;
-    }
+
   gcc_assert (!TYPE_SIZE_UNIT (t1) || !TYPE_SIZE_UNIT (t2)
              || operand_equal_p (TYPE_SIZE_UNIT (t1),
                                  TYPE_SIZE_UNIT (t2), 0));
-  return true;
+  return type_variants_equivalent_p (t1, t2, warn, warned);
 }
 
 /* Return true if TYPE1 and TYPE2 are equivalent for One Definition Rule.  */
index 7d663ec6b0eebbbf75136f1d58a40866b7f85743..371b2fbdb98b71a59f02b61fcd8cae1f9017ce83 100644 (file)
@@ -83,7 +83,7 @@ bool type_known_to_have_no_derivations_p (tree);
 bool contains_polymorphic_type_p (const_tree);
 void register_odr_type (tree);
 bool types_must_be_same_for_odr (tree, tree);
-bool types_odr_comparable (tree, tree, bool strict = false);
+bool types_odr_comparable (tree, tree);
 cgraph_node *try_speculative_devirtualization (tree, HOST_WIDE_INT,
                                               ipa_polymorphic_call_context);
 void warn_types_mismatch (tree t1, tree t2, location_t loc1 = UNKNOWN_LOCATION,
@@ -179,6 +179,7 @@ polymorphic_type_binfo_p (const_tree binfo)
 inline bool
 type_with_linkage_p (const_tree t)
 {
+  gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t);
   if (!TYPE_NAME (t) || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL)
     return false;
 
index 598492df5277a5d2dc37c73cff34d6e15bad20ba..2d52d4a8f4e34affef63c5221ba449906b355ad7 100644 (file)
@@ -1827,7 +1827,7 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
                     type canonical of a derived type in the same SCC.  */
                  if (!TYPE_CANONICAL (t))
                    gimple_register_canonical_type (t);
-                 if (odr_type_p (t))
+                 if (TYPE_MAIN_VARIANT (t) == t && odr_type_p (t))
                    odr_types.safe_push (t);
                }
              /* Link shared INTEGER_CSTs into TYPE_CACHED_VALUEs of its
index 2e45f9db2e34ddccbef87a57a335d03bdcb0f5a2..0ef96ba561285406e4e3e7aceb5fd1ab58ca9d56 100644 (file)
@@ -4958,8 +4958,7 @@ extern tree block_ultimate_origin (const_tree);
 extern tree get_binfo_at_offset (tree, poly_int64, tree);
 extern bool virtual_method_call_p (const_tree);
 extern tree obj_type_ref_class (const_tree ref);
-extern bool types_same_for_odr (const_tree type1, const_tree type2,
-                               bool strict=false);
+extern bool types_same_for_odr (const_tree type1, const_tree type2);
 extern bool contains_bitfld_component_ref_p (const_tree);
 extern bool block_may_fallthru (const_tree);
 extern void using_eh_for_cleanups (void);