* Last part of verify_type_vairant checks
@ 2015-05-15 3:53 Jan Hubicka
2015-05-15 21:27 ` Eric Botcazou
0 siblings, 1 reply; 2+ messages in thread
From: Jan Hubicka @ 2015-05-15 3:53 UTC (permalink / raw)
To: gcc-patches, ebotcazou
Hi,
this patch adds checks of tree_base and type_common flags/fields. I also refactored
code to use verify_type_variant_flag macro for better brevity and added a comment
of what can differ between variants and why. Hope it will be useful :)
There seems to be 3 issues:
- C++ FE seems to build type variants that differ in TYPE_FINAL that is not supposed
to happen. I will try to debug it tomorrow.
- Ada builds !TYPE_ARTIFICIAL variant of TYPE_ARTIFICIAL type.
Eric, I can not really make sense of this. Is this expected?
If we have artificial type, how it can become not?
- During Ada builds there are types that differ in TYPE_SIZES_GIMPLIFIED.
This is probably harmless but I am not sure it ishappen to happen.
Bootstrapped/regtested ppc64-linux, will commit it tomorrow if there are no
complains.
Honza
* tree.c (verify_type_variant): Verify tree_base and type_common flags.
(verify_type): Verify STRING_FLAG
Index: tree.c
===================================================================
--- tree.c (revision 223021)
+++ tree.c (working copy)
@@ -12474,6 +12474,7 @@ element_mode (const_tree t)
t = TREE_TYPE (t);
return TYPE_MODE (t);
}
+
/* Veirfy that basic properties of T match TV and thus T can be a variant of
TV. TV should be the more specified variant (i.e. the main variant). */
@@ -12481,85 +12482,129 @@ element_mode (const_tree t)
static bool
verify_type_variant (const_tree t, tree tv)
{
- if (TREE_CODE (t) != TREE_CODE (tv))
- {
- error ("type variant has different TREE_CODE");
- debug_tree (tv);
- return false;
- }
- if (COMPLETE_TYPE_P (t) && TYPE_SIZE (t) != TYPE_SIZE (tv))
- {
- error ("type variant has different TYPE_SIZE");
- debug_tree (tv);
- error ("type variant's TYPE_SIZE");
- debug_tree (TYPE_SIZE (tv));
- error ("type's TYPE_SIZE");
- debug_tree (TYPE_SIZE (t));
- return false;
- }
- if (COMPLETE_TYPE_P (t)
- && TYPE_SIZE_UNIT (t) != TYPE_SIZE_UNIT (tv)
- /* FIXME: ideally we should compare pointer equality, but java FE produce
- variants where size is INTEGER_CST of different type (int wrt size_type)
- during libjava biuld. */
- && !operand_equal_p (TYPE_SIZE_UNIT (t), TYPE_SIZE_UNIT (tv), 0))
- {
- error ("type variant has different TYPE_SIZE_UNIT");
- debug_tree (tv);
- error ("type variant's TYPE_SIZE_UNIT");
- debug_tree (TYPE_SIZE_UNIT (tv));
- error ("type's TYPE_SIZE_UNIT");
- debug_tree (TYPE_SIZE_UNIT (t));
- return false;
+ /* Type variant can differ by:
+
+ - TYPE_QUALS: TYPE_READONLY, TYPE_VOLATILE, TYPE_ATOMIC, TYPE_RESTRICT,
+ ENCODE_QUAL_ADDR_SPACE.
+ - main variant may be TYPE_COMPLETE_P and variant types !TYPE_COMPLETE_P
+ in this case some values may not be set in the variant types
+ (see TYPE_COMPLETE_P checks).
+ - it is possible to have TYPE_ARTIFICIAL variant of non-artifical type
+ - by TYPE_NAME and attributes (i.e. when variant originate by typedef)
+ - TYPE_CANONICAL (TYPE_ALIAS_SET is the same among variants)
+ - by the alignment: TYPE_ALIGN and TYPE_USER_ALIGN
+ - during LTO by TYPE_CONTEXT if type is TYPE_FILE_SCOPE_P
+ this is necessary to make it possible to merge types form different TUs
+ - arrays, pointers and references may have TREE_TYPE that is a variant
+ of TREE_TYPE of their main variants.
+ - aggregates may have new TYPE_FIELDS list that list variants of
+ the main variant TYPE_FIELDS.
+ - vector types may differ by TYPE_VECTOR_OPAQUE
+ - TYPE_METHODS is always NULL for vairant types and maintained for
+ main variant only.
+ */
+
+ /* Convenience macro for matching individual fields. */
+#define verify_variant_match(flag) \
+ do { \
+ if (flag (tv) != flag (t)) \
+ { \
+ error ("type variant differs by " #flag "."); \
+ debug_tree (tv); \
+ return false; \
+ } \
+ } while (false)
+
+ /* tree_base checks. */
+
+ verify_variant_match (TREE_CODE);
+ /* FIXME: Ada builds non-artificial variants of artificial types. */
+ if (TYPE_ARTIFICIAL (tv) && 0)
+ verify_variant_match (TYPE_ARTIFICIAL);
+ if (POINTER_TYPE_P (tv))
+ verify_variant_match (TYPE_REF_CAN_ALIAS_ALL);
+ /* FIXME: TYPE_SIZES_GIMPLIFIED may differs for Ada build. */
+ verify_variant_match (TYPE_UNSIGNED);
+ verify_variant_match (TYPE_ALIGN_OK);
+ verify_variant_match (TYPE_PACKED);
+ if (TREE_CODE (t) == REFERENCE_TYPE)
+ verify_variant_match (TYPE_REF_IS_RVALUE);
+ verify_variant_match (TYPE_SATURATING);
+ /* FIXME: This check trigger during libstdc++ build. */
+ if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t) && 0)
+ verify_variant_match (TYPE_FINAL_P);
+
+ /* tree_type_common checks. */
+
+ if (COMPLETE_TYPE_P (t))
+ {
+ verify_variant_match (TYPE_SIZE);
+ verify_variant_match (TYPE_MODE);
+ if (TYPE_SIZE_UNIT (t) != TYPE_SIZE_UNIT (tv)
+ /* FIXME: ideally we should compare pointer equality, but java FE
+ produce variants where size is INTEGER_CST of different type (int
+ wrt size_type) during libjava biuld. */
+ && !operand_equal_p (TYPE_SIZE_UNIT (t), TYPE_SIZE_UNIT (tv), 0))
+ {
+ error ("type variant has different TYPE_SIZE_UNIT");
+ debug_tree (tv);
+ error ("type variant's TYPE_SIZE_UNIT");
+ debug_tree (TYPE_SIZE_UNIT (tv));
+ error ("type's TYPE_SIZE_UNIT");
+ debug_tree (TYPE_SIZE_UNIT (t));
+ return false;
+ }
}
+ verify_variant_match (TYPE_PRECISION);
+ verify_variant_match (TYPE_NO_FORCE_BLK);
+ verify_variant_match (TYPE_NEEDS_CONSTRUCTING);
+ if (RECORD_OR_UNION_TYPE_P (t))
+ verify_variant_match (TYPE_TRANSPARENT_AGGR);
+ else if (TREE_CODE (t) == ARRAY_TYPE)
+ verify_variant_match (TYPE_NONALIASED_COMPONENT);
+ /* During LTO we merge variant lists from diferent translation units
+ that may differ BY TYPE_CONTEXT that in turn may point
+ to TRANSLATION_UNIT_DECL.
+ Ada also builds variants of types with different TYPE_CONTEXT. */
+ if ((!in_lto_p || !TYPE_FILE_SCOPE_P (t)) && 0)
+ verify_variant_match (TYPE_CONTEXT);
+ verify_variant_match (TYPE_STRING_FLAG);
+ if (TYPE_ALIAS_SET_KNOWN_P (t) && TYPE_ALIAS_SET_KNOWN_P (tv))
+ verify_variant_match (TYPE_ALIAS_SET);
+
+ /* tree_type_non_common checks. */
+
/* FIXME: C FE uses TYPE_VFIELD to record C_TYPE_INCOMPLETE_VARS
- and danagle the pointer from time to time. */
+ and dangle the pointer from time to time. */
if (RECORD_OR_UNION_TYPE_P (t) && TYPE_VFIELD (t) != TYPE_VFIELD (tv)
- && (!TYPE_VFIELD (tv) || TREE_CODE (TYPE_VFIELD (tv)) != TREE_LIST))
+ && (in_lto_p || !TYPE_VFIELD (tv)
+ || TREE_CODE (TYPE_VFIELD (tv)) != TREE_LIST))
{
error ("type variant has different TYPE_VFIELD");
debug_tree (tv);
return false;
}
- if (((TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
- || TREE_CODE (t) == INTEGER_TYPE
- || TREE_CODE (t) == BOOLEAN_TYPE
- || TREE_CODE (t) == REAL_TYPE
- || TREE_CODE (t) == FIXED_POINT_TYPE)
- && (TYPE_MAX_VALUE (t) != TYPE_MAX_VALUE (tv)
- || TYPE_MIN_VALUE (t) != TYPE_MIN_VALUE (tv)))
+ if ((TREE_CODE (t) == ENUMERAL_TYPE && COMPLETE_TYPE_P (t))
+ || TREE_CODE (t) == INTEGER_TYPE
+ || TREE_CODE (t) == BOOLEAN_TYPE
+ || TREE_CODE (t) == REAL_TYPE
+ || TREE_CODE (t) == FIXED_POINT_TYPE)
{
- error ("type variant has different TYPE_MAX_VALUE or TYPE_MIN_VALUE");
- debug_tree (tv);
- return false;
- }
- if (TREE_CODE (t) == METHOD_TYPE
- && TYPE_METHOD_BASETYPE (t) != TYPE_METHOD_BASETYPE (tv))
- {
- error ("type variant has different TYPE_METHOD_BASETYPE");
- debug_tree (tv);
- return false;
+ verify_variant_match (TYPE_MAX_VALUE);
+ verify_variant_match (TYPE_MIN_VALUE);
}
+ if (TREE_CODE (t) == METHOD_TYPE)
+ verify_variant_match (TYPE_METHOD_BASETYPE);
if (RECORD_OR_UNION_TYPE_P (t) && TYPE_METHODS (t))
{
error ("type variant has TYPE_METHODS");
debug_tree (tv);
return false;
}
- if (TREE_CODE (t) == OFFSET_TYPE
- && TYPE_OFFSET_BASETYPE (t) != TYPE_OFFSET_BASETYPE (tv))
- {
- error ("type variant has different TYPE_OFFSET_BASETYPE");
- debug_tree (tv);
- return false;
- }
- if (TREE_CODE (t) == ARRAY_TYPE
- && TYPE_ARRAY_MAX_SIZE (t) != TYPE_ARRAY_MAX_SIZE (tv))
- {
- error ("type variant has different TYPE_ARRAY_MAX_SIZE");
- debug_tree (tv);
- return false;
- }
+ if (TREE_CODE (t) == OFFSET_TYPE)
+ verify_variant_match (TYPE_OFFSET_BASETYPE);
+ if (TREE_CODE (t) == ARRAY_TYPE)
+ verify_variant_match (TYPE_ARRAY_MAX_SIZE);
/* FIXME: Be lax and allow TYPE_BINFO to be missing in variant types
or even type's main variant. This is needed to make bootstrap pass
and the bug seems new in GCC 5.
@@ -12587,28 +12632,10 @@ verify_type_variant (const_tree t, tree
}
/* 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;
- }
+ if (TREE_CODE (t) == ENUMERAL_TYPE)
+ verify_variant_match (TYPE_VALUES);
+ else if (TREE_CODE (t) == ARRAY_TYPE)
+ verify_variant_match (TYPE_DOMAIN);
/* 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)
@@ -12646,13 +12673,8 @@ verify_type_variant (const_tree t, tree
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;
- }
+ else if ((TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE))
+ verify_variant_match (TYPE_ARG_TYPES);
/* 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
@@ -12671,15 +12693,11 @@ verify_type_variant (const_tree t, tree
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;
+#undef verify_type_variant
}
+
/* Verify type T. */
void
@@ -12972,6 +12990,27 @@ verify_type (const_tree t)
error ("TYPE_CACHED_VALUES_P is set while it should not");
error_found = true;
}
+ if (TYPE_STRING_FLAG (t)
+ && TREE_CODE (t) != ARRAY_TYPE && TREE_CODE (t) != INTEGER_TYPE)
+ {
+ error ("TYPE_STRING_FLAG is set on wrong type code");
+ error_found = true;
+ }
+ else if (TYPE_STRING_FLAG (t))
+ {
+ const_tree b = t;
+ if (TREE_CODE (b) == ARRAY_TYPE)
+ b = TREE_TYPE (t);
+ /* Java builds arrays with TYPE_STRING_FLAG of promoted_char_type
+ that is 32bits. */
+ if (TREE_CODE (b) != INTEGER_TYPE)
+ {
+ error ("TYPE_STRING_FLAG is set on type that does not look like "
+ "char nor array of chars");
+ error_found = true;
+ }
+ }
+
if (error_found)
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Last part of verify_type_vairant checks
2015-05-15 3:53 Last part of verify_type_vairant checks Jan Hubicka
@ 2015-05-15 21:27 ` Eric Botcazou
0 siblings, 0 replies; 2+ messages in thread
From: Eric Botcazou @ 2015-05-15 21:27 UTC (permalink / raw)
To: Jan Hubicka; +Cc: gcc-patches, Pierre-Marie de Rodat
> - Ada builds !TYPE_ARTIFICIAL variant of TYPE_ARTIFICIAL type.
> Eric, I can not really make sense of this. Is this expected?
> If we have artificial type, how it can become not?
Yes, that's a bit unexpected and probably comes from the case where we build a
variant and it's not really appropriate to do so (gnat_pushdecl):
/* ??? Copy and original type are not supposed to be variant but we
really need a variant for the placeholder machinery to work. */
if (TYPE_IS_FAT_POINTER_P (t))
tt = build_variant_type_copy (t);
else
{
/* TYPE_NEXT_PTR_TO is a chain of main variants. */
tt = build_distinct_type_copy (TYPE_MAIN_VARIANT (t));
if (TREE_CODE (t) == POINTER_TYPE)
TYPE_NEXT_PTR_TO (TYPE_MAIN_VARIANT (t)) = tt;
tt = build_qualified_type (tt, TYPE_QUALS (t));
}
On the other hand, if the type declared in the source code is volatile, one
could imagine that the non-volatile main variant be TYPE_ARTIFICIAL and the
declared type be !TYPE_ARTIFICIAL.
> - During Ada builds there are types that differ in TYPE_SIZES_GIMPLIFIED.
> This is probably harmless but I am not sure it ishappen to happen.
That it's harmless I'm sure, otherwise it would already have bitten us. :-)
But I agree that it would be better to always gimplify the main variant first
and propagate to the other variants, as done in gimplify_type_sizes.
If you have a patchlet for this one, you can open a PR and attach it.
--
Eric Botcazou
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-05-15 21:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-15 3:53 Last part of verify_type_vairant checks Jan Hubicka
2015-05-15 21:27 ` Eric Botcazou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).