* tree.c (verify_type_variant): Check TYPE_VALUES_RAW and TYPE_PRECISION
authorJan Hubicka <hubicka@ucw.cz>
Mon, 11 May 2015 02:51:51 +0000 (04:51 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 11 May 2015 02:51:51 +0000 (02:51 +0000)
From-SVN: r222991

gcc/ChangeLog
gcc/tree.c

index d2db83475a77e64ad9e68c7e05ab61b72fcff9e8..c305d2efa45f61804e2ede82b144d9989c710cc2 100644 (file)
@@ -1,3 +1,7 @@
+2015-05-09  Jan Hubicka  <hubicka@ucw.cz>
+
+       * tree.c (verify_type_variant): Check TYPE_VALUES_RAW and TYPE_PRECISION
+
 2015-05-09  Jan Hubicka  <hubicka@ucw.cz>
 
        Patch by Richard Biener
index b4dceed31dc227f426feab96fb40b30efbcadcd4..0c97667b6a047cc49f91148320bc9848bcd1496d 100644 (file)
@@ -12577,6 +12577,98 @@ verify_type_variant (const_tree t, tree tv)
       debug_tree (TYPE_BINFO (t));
       return false;
     }
+
+  /* Check various uses of TYPE_VALUES_RAW.  */
+  if (TREE_CODE (t) == ENUMERAL_TYPE
+      && TYPE_VALUES (t) != TYPE_VALUES (tv))
+    {
+      error ("type variant has different TYPE_VALUES");
+      debug_tree (tv);
+      error ("type variant's TYPE_VALUES");
+      debug_tree (TYPE_VALUES (tv));
+      error ("type's TYPE_VALUES");
+      debug_tree (TYPE_VALUES (t));
+      return false;
+    }
+  else if (TREE_CODE (t) == ARRAY_TYPE
+          && TYPE_DOMAIN (t) != TYPE_DOMAIN (tv))
+    {
+      error ("type variant has different TYPE_DOMAIN");
+      debug_tree (tv);
+      error ("type variant's TYPE_DOMAIN");
+      debug_tree (TYPE_DOMAIN (tv));
+      error ("type's TYPE_DOMAIN");
+      debug_tree (TYPE_DOMAIN (t));
+      return false;
+    }
+  /* Permit incomplete variants of complete type.  While FEs may complete
+     all variants, this does not happen for C++ templates in all cases.  */
+  else if (RECORD_OR_UNION_TYPE_P (t)
+          && COMPLETE_TYPE_P (t)
+          && TYPE_FIELDS (t) != TYPE_FIELDS (tv))
+    {
+      tree f1, f2;
+
+      /* Fortran builds qualified variants as new records with items of
+        qualified type. Verify that they looks same.  */
+      for (f1 = TYPE_FIELDS (t), f2 = TYPE_FIELDS (tv);
+          f1 && f2;
+          f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
+       if (TREE_CODE (f1) != FIELD_DECL || TREE_CODE (f2) != FIELD_DECL
+           || (TYPE_MAIN_VARIANT (TREE_TYPE (f1))
+                != TYPE_MAIN_VARIANT (TREE_TYPE (f2))
+               /* FIXME: gfc_nonrestricted_type builds all types as variants
+                  with exception of pointer types.  It deeply copies the type
+                  which means that we may end up with a variant type
+                  referring non-variant pointer.  We may change it to
+                  produce types as variants, too, like
+                  objc_get_protocol_qualified_type does.  */
+               && !POINTER_TYPE_P (TREE_TYPE (f1)))
+           || DECL_FIELD_OFFSET (f1) != DECL_FIELD_OFFSET (f2)
+           || DECL_FIELD_BIT_OFFSET (f1) != DECL_FIELD_BIT_OFFSET (f2))
+         break;
+      if (f1 || f2)
+       {
+         error ("type variant has different TYPE_FIELDS");
+         debug_tree (tv);
+         error ("first mismatch is field");
+         debug_tree (f1);
+         error ("and field");
+         debug_tree (f2);
+          return false;
+       }
+    }
+  else if ((TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
+          && TYPE_ARG_TYPES (t) != TYPE_ARG_TYPES (tv))
+    {
+      error ("type variant has different TYPE_ARG_TYPES");
+      debug_tree (tv);
+      return false;
+    }
+  /* For C++ the qualified variant of array type is really an array type
+     of qualified TREE_TYPE.
+     objc builds variants of pointer where pointer to type is a variant, too
+     in objc_get_protocol_qualified_type.  */
+  if (TREE_TYPE (t) != TREE_TYPE (tv)
+      && ((TREE_CODE (t) != ARRAY_TYPE
+          && !POINTER_TYPE_P (t))
+         || TYPE_MAIN_VARIANT (TREE_TYPE (t))
+            != TYPE_MAIN_VARIANT (TREE_TYPE (tv))))
+    {
+      error ("type variant has different TREE_TYPE");
+      debug_tree (tv);
+      error ("type variant's TREE_TYPE");
+      debug_tree (TREE_TYPE (tv));
+      error ("type's TREE_TYPE");
+      debug_tree (TREE_TYPE (t));
+      return false;
+    }
+  if (TYPE_PRECISION (t) != TYPE_PRECISION (tv))
+    {
+      error ("type variant has different TYPE_PRECISION");
+      debug_tree (tv);
+      return false;
+    }
   return true;
 }