TYPE_QUALS (type) | TYPE_QUALS (like));
}
\f
-/* Return the composite type of two compatible types, or the common
- type for two arithmetic types under the usual arithmetic
- conversions.
+/* Return the composite type of two compatible types.
- Unless both types are arithmetic types, we assume that comptypes
- has already been done and returned 1; if that isn't so, this may
- crash. In particular, we assume that qualifiers match.
-
- This is the type for the result of most arithmetic operations
- if the operands have the given two types. */
+ We assume that comptypes has already been done and returned
+ nonzero; if that isn't so, this may crash. In particular, we
+ assume that qualifiers match. */
tree
-common_type (tree t1, tree t2)
+composite_type (tree t1, tree t2)
{
enum tree_code code1;
enum tree_code code2;
if (t2 == error_mark_node)
return t1;
+ code1 = TREE_CODE (t1);
+ code2 = TREE_CODE (t2);
+
/* Merge the attributes. */
attributes = targetm.merge_type_attributes (t1, t2);
- /* Treat an enum type as the unsigned integer type of the same width. */
-
- if (TREE_CODE (t1) == ENUMERAL_TYPE)
- t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
- if (TREE_CODE (t2) == ENUMERAL_TYPE)
- t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
-
- code1 = TREE_CODE (t1);
- code2 = TREE_CODE (t2);
+ /* If one is an enumerated type and the other is the compatible
+ integer type, the composite type might be either of the two
+ (DR#013 question 3). For consistency, use the enumerated type as
+ the composite type. */
- /* If one type is complex, form the common type of the non-complex
- components, then make that complex. Use T1 or T2 if it is the
- required type. */
- if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
- {
- tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
- tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
- tree subtype = common_type (subtype1, subtype2);
+ if (code1 == ENUMERAL_TYPE && code2 == INTEGER_TYPE)
+ return t1;
+ if (code2 == ENUMERAL_TYPE && code1 == INTEGER_TYPE)
+ return t2;
- if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
- return build_type_attribute_variant (t1, attributes);
- else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
- return build_type_attribute_variant (t2, attributes);
- else
- return build_type_attribute_variant (build_complex_type (subtype),
- attributes);
- }
+ if (code1 != code2)
+ abort ();
switch (code1)
{
- case INTEGER_TYPE:
- case REAL_TYPE:
- /* If only one is real, use it as the result. */
-
- if (code1 == REAL_TYPE && code2 != REAL_TYPE)
- return build_type_attribute_variant (t1, attributes);
-
- if (code2 == REAL_TYPE && code1 != REAL_TYPE)
- return build_type_attribute_variant (t2, attributes);
-
- /* Both real or both integers; use the one with greater precision. */
-
- if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
- return build_type_attribute_variant (t1, attributes);
- else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
- return build_type_attribute_variant (t2, attributes);
-
- /* Same precision. Prefer long longs to longs to ints when the
- same precision, following the C99 rules on integer type rank
- (which are equivalent to the C90 rules for C90 types).
- Make sure that we don't lose the type qualifications when
- creating the new variant. */
-
- if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
- || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
- {
- t1 = build_qualified_type (long_long_unsigned_type_node,
- TYPE_QUALS (t1));
- return build_type_attribute_variant (t1, attributes);
- }
-
- if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
- || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
- {
- tree ntype;
-
- if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
- ntype = long_long_unsigned_type_node;
- else
- ntype = long_long_integer_type_node;
-
- ntype = build_qualified_type (ntype, TYPE_QUALS (t1));
- return build_type_attribute_variant (ntype, attributes);
- }
-
- if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
- || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
- {
- t1 = build_qualified_type (long_unsigned_type_node,
- TYPE_QUALS (t1));
- return build_type_attribute_variant (t1, attributes);
- }
-
- if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
- || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
- {
- tree ntype;
-
- /* But preserve unsignedness from the other type,
- since long cannot hold all the values of an unsigned int. */
- if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
- ntype = long_unsigned_type_node;
- else
- ntype = long_integer_type_node;
-
- ntype = build_qualified_type (ntype, TYPE_QUALS (t1));
- return build_type_attribute_variant (ntype, attributes);
- }
-
- /* Likewise, prefer long double to double even if same size. */
- if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
- || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
- {
- t1 = build_qualified_type (long_double_type_node,
- TYPE_QUALS (t1));
- return build_type_attribute_variant (t1, attributes);
- }
-
- /* Otherwise prefer the unsigned one. */
-
- if (TYPE_UNSIGNED (t1))
- return build_type_attribute_variant (t1, attributes);
- else
- return build_type_attribute_variant (t2, attributes);
-
case POINTER_TYPE:
- /* For two pointers, do this recursively on the target type,
- and combine the qualifiers of the two types' targets. */
- /* This code was turned off; I don't know why.
- But ANSI C specifies doing this with the qualifiers.
- So I turned it on again. */
+ /* For two pointers, do this recursively on the target type. */
{
tree pointed_to_1 = TREE_TYPE (t1);
tree pointed_to_2 = TREE_TYPE (t2);
- tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
- TYPE_MAIN_VARIANT (pointed_to_2));
- t1 = build_pointer_type (c_build_qualified_type
- (target,
- TYPE_QUALS (pointed_to_1) |
- TYPE_QUALS (pointed_to_2)));
+ tree target = composite_type (pointed_to_1, pointed_to_2);
+ t1 = build_pointer_type (target);
return build_type_attribute_variant (t1, attributes);
}
case ARRAY_TYPE:
{
- tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
+ tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
/* Save space: see if the result is identical to one of the args. */
if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
return build_type_attribute_variant (t1, attributes);
/* Function types: prefer the one that specified arg types.
If both do, merge the arg types. Also merge the return types. */
{
- tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
+ tree valtype = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
tree p1 = TYPE_ARG_TYPES (t1);
tree p2 = TYPE_ARG_TYPES (t2);
int len;
goto parm_done;
}
}
- TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2));
+ TREE_VALUE (n) = composite_type (TREE_VALUE (p1), TREE_VALUE (p2));
parm_done: ;
}
}
}
+
+/* Return the type of a conditional expression between pointers to
+ possibly differently qualified versions of compatible types.
+
+ We assume that comp_target_types has already been done and returned
+ nonzero; if that isn't so, this may crash. */
+
+static tree
+common_pointer_type (tree t1, tree t2)
+{
+ tree attributes;
+ tree pointed_to_1;
+ tree pointed_to_2;
+ tree target;
+
+ /* Save time if the two types are the same. */
+
+ if (t1 == t2) return t1;
+
+ /* If one type is nonsense, use the other. */
+ if (t1 == error_mark_node)
+ return t2;
+ if (t2 == error_mark_node)
+ return t1;
+
+ if (TREE_CODE (t1) != POINTER_TYPE || TREE_CODE (t2) != POINTER_TYPE)
+ abort ();
+
+ /* Merge the attributes. */
+ attributes = targetm.merge_type_attributes (t1, t2);
+
+ /* Find the composite type of the target types, and combine the
+ qualifiers of the two types' targets. */
+ pointed_to_1 = TREE_TYPE (t1);
+ pointed_to_2 = TREE_TYPE (t2);
+ target = composite_type (TYPE_MAIN_VARIANT (pointed_to_1),
+ TYPE_MAIN_VARIANT (pointed_to_2));
+ t1 = build_pointer_type (c_build_qualified_type
+ (target,
+ TYPE_QUALS (pointed_to_1) |
+ TYPE_QUALS (pointed_to_2)));
+ return build_type_attribute_variant (t1, attributes);
+}
+
+/* Return the common type for two arithmetic types under the usual
+ arithmetic conversions. The default conversions have already been
+ applied, and enumerated types converted to their compatible integer
+ types. The resulting type is unqualified and has no attributes.
+
+ This is the type for the result of most arithmetic operations
+ if the operands have the given two types. */
+
+tree
+common_type (tree t1, tree t2)
+{
+ enum tree_code code1;
+ enum tree_code code2;
+
+ /* If one type is nonsense, use the other. */
+ if (t1 == error_mark_node)
+ return t2;
+ if (t2 == error_mark_node)
+ return t1;
+
+ if (TYPE_QUALS (t1) != TYPE_UNQUALIFIED)
+ t1 = TYPE_MAIN_VARIANT (t1);
+
+ if (TYPE_QUALS (t2) != TYPE_UNQUALIFIED)
+ t2 = TYPE_MAIN_VARIANT (t2);
+
+ if (TYPE_ATTRIBUTES (t1) != NULL_TREE)
+ t1 = build_type_attribute_variant (t1, NULL_TREE);
+
+ if (TYPE_ATTRIBUTES (t2) != NULL_TREE)
+ t2 = build_type_attribute_variant (t2, NULL_TREE);
+
+ /* Save time if the two types are the same. */
+
+ if (t1 == t2) return t1;
+
+ code1 = TREE_CODE (t1);
+ code2 = TREE_CODE (t2);
+
+ if (code1 != VECTOR_TYPE && code1 != COMPLEX_TYPE
+ && code1 != REAL_TYPE && code1 != INTEGER_TYPE)
+ abort ();
+
+ if (code2 != VECTOR_TYPE && code2 != COMPLEX_TYPE
+ && code2 != REAL_TYPE && code2 != INTEGER_TYPE)
+ abort ();
+
+ /* If one type is a vector type, return that type. (How the usual
+ arithmetic conversions apply to the vector types extension is not
+ precisely specified.) */
+ if (code1 == VECTOR_TYPE)
+ return t1;
+
+ if (code2 == VECTOR_TYPE)
+ return t2;
+
+ /* If one type is complex, form the common type of the non-complex
+ components, then make that complex. Use T1 or T2 if it is the
+ required type. */
+ if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
+ {
+ tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
+ tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
+ tree subtype = common_type (subtype1, subtype2);
+
+ if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
+ return t1;
+ else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
+ return t2;
+ else
+ return build_complex_type (subtype);
+ }
+
+ /* If only one is real, use it as the result. */
+
+ if (code1 == REAL_TYPE && code2 != REAL_TYPE)
+ return t1;
+
+ if (code2 == REAL_TYPE && code1 != REAL_TYPE)
+ return t2;
+
+ /* Both real or both integers; use the one with greater precision. */
+
+ if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
+ return t1;
+ else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
+ return t2;
+
+ /* Same precision. Prefer long longs to longs to ints when the
+ same precision, following the C99 rules on integer type rank
+ (which are equivalent to the C90 rules for C90 types). */
+
+ if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
+ || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
+ return long_long_unsigned_type_node;
+
+ if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
+ || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
+ {
+ if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+ return long_long_unsigned_type_node;
+ else
+ return long_long_integer_type_node;
+ }
+
+ if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
+ || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
+ return long_unsigned_type_node;
+
+ if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
+ || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
+ {
+ /* But preserve unsignedness from the other type,
+ since long cannot hold all the values of an unsigned int. */
+ if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+ return long_unsigned_type_node;
+ else
+ return long_integer_type_node;
+ }
+
+ /* Likewise, prefer long double to double even if same size. */
+ if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
+ || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
+ return long_double_type_node;
+
+ /* Otherwise prefer the unsigned one. */
+
+ if (TYPE_UNSIGNED (t1))
+ return t1;
+ else
+ return t2;
+}
\f
/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
or various other operations. Return 2 if they are compatible
else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
{
if (comp_target_types (type1, type2, 1))
- result_type = common_type (type1, type2);
+ result_type = common_pointer_type (type1, type2);
else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
&& TREE_CODE (orig_op1) != NOP_EXPR)
result_type = qualify_type (type2, type1);
Otherwise, the targets must be compatible
and both must be object or both incomplete. */
if (comp_target_types (type0, type1, 1))
- result_type = common_type (type0, type1);
+ result_type = common_pointer_type (type0, type1);
else if (VOID_TYPE_P (tt0))
{
/* op0 != orig_op0 detects the case of something
{
if (comp_target_types (type0, type1, 1))
{
- result_type = common_type (type0, type1);
+ result_type = common_pointer_type (type0, type1);
if (pedantic
&& TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
{
if (comp_target_types (type0, type1, 1))
{
- result_type = common_type (type0, type1);
+ result_type = common_pointer_type (type0, type1);
if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
!= !COMPLETE_TYPE_P (TREE_TYPE (type1)))
pedwarn ("comparison of complete and incomplete pointers");