From: Richard Kenner Date: Fri, 6 May 1994 22:29:58 +0000 (-0400) Subject: (common_type): Add attribute merging. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4b027d160e235705a6a3928d26e4fac9a046a627;p=gcc.git (common_type): Add attribute merging. (comp_types): Use COMP_TYPE_ATTRIBUTES macro. From-SVN: r7254 --- diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 5b491979ba4..ba2530679f7 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -178,6 +178,7 @@ common_type (t1, t2) { register enum tree_code code1; register enum tree_code code2; + tree attributes; /* Save time if the two types are the same. */ @@ -189,6 +190,40 @@ common_type (t1, t2) if (t2 == error_mark_node) return t1; + /* Merge the attributes */ + + { register tree a1, a2; + a1 = TYPE_ATTRIBUTES (t1); + a2 = TYPE_ATTRIBUTES (t2); + + /* Either one unset? Take the set one. */ + + if (!(attributes = a1)) + attributes = a2; + + /* One that completely contains the other? Take it. */ + + else if (a2 && !attribute_list_contained (a1, a2)) + if (attribute_list_contained (a2, a1)) + attributes = a2; + else + { + /* Pick the longest list, and hang on the other + list. */ + + if (list_length (a1) < list_length (a2)) + attributes = a2, a2 = a1; + + for (; a2; a2 = TREE_CHAIN (a2)) + if (!value_member (attributes, a2)) + { + a1 = copy_node (a2); + TREE_CHAIN (a1) = attributes; + attributes = a1; + } + } + } + /* Treat an enum type as the unsigned integer type of the same width. */ if (TREE_CODE (t1) == ENUMERAL_TYPE) @@ -209,11 +244,12 @@ common_type (t1, t2) tree subtype = common_type (subtype1, subtype2); if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype) - return t1; + return build_type_attribute_variant (t1, attributes); else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype) - return t2; + return build_type_attribute_variant (t2, attributes); else - return build_complex_type (subtype); + return build_type_attribute_variant (build_complex_type (subtype), + attributes); } switch (code1) @@ -223,23 +259,24 @@ common_type (t1, t2) /* If only one is real, use it as the result. */ if (code1 == REAL_TYPE && code2 != REAL_TYPE) - return t1; + return build_type_attribute_variant (t1, attributes); if (code2 == REAL_TYPE && code1 != REAL_TYPE) - return t2; + 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 t1; + return build_type_attribute_variant (t1, attributes); else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1)) - return t2; + return build_type_attribute_variant (t2, attributes); /* Same precision. Prefer longs to ints even when same size. */ if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node) - return long_unsigned_type_node; + return build_type_attribute_variant (long_unsigned_type_node, + attributes); if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node || TYPE_MAIN_VARIANT (t2) == long_integer_type_node) @@ -247,15 +284,18 @@ common_type (t1, t2) /* But preserve unsignedness from the other type, since long cannot hold all the values of an unsigned int. */ if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2)) - return long_unsigned_type_node; - return long_integer_type_node; + t1 = long_unsigned_type_node; + else + t1 = long_integer_type_node; + return build_type_attribute_variant (t1, attributes); } /* Otherwise prefer the unsigned one. */ if (TREE_UNSIGNED (t1)) - return t1; - else return t2; + 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, @@ -270,10 +310,13 @@ common_type (t1, t2) = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2)); int volatilep = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2)); - return build_pointer_type (c_build_type_variant (target, constp, volatilep)); + t1 = build_pointer_type (c_build_type_variant (target, constp, + volatilep)); + return build_type_attribute_variant (t1, attributes); } #if 0 - return build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2))); + t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2))); + return build_type_attribute_variant (t1, attributes); #endif case ARRAY_TYPE: @@ -281,11 +324,12 @@ common_type (t1, t2) tree elt = common_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 t1; + return build_type_attribute_variant (t1, attributes); if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)) - return t2; + return build_type_attribute_variant (t2, attributes); /* Merge the element types, and have a size if either arg has one. */ - return build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2)); + t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2)); + return build_type_attribute_variant (t1, attributes); } case FUNCTION_TYPE: @@ -301,15 +345,21 @@ common_type (t1, t2) /* Save space: see if the result is identical to one of the args. */ if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2)) - return t1; + return build_type_attribute_variant (t1, attributes); if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1)) - return t2; + return build_type_attribute_variant (t2, attributes); /* Simple way if one arg fails to specify argument types. */ if (TYPE_ARG_TYPES (t1) == 0) - return build_function_type (valtype, TYPE_ARG_TYPES (t2)); + { + t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2)); + return build_type_attribute_variant (t1, attributes); + } if (TYPE_ARG_TYPES (t2) == 0) - return build_function_type (valtype, TYPE_ARG_TYPES (t1)); + { + t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1)); + return build_type_attribute_variant (t1, attributes); + } /* If both args specify argument types, we must merge the two lists, argument by argument. */ @@ -373,11 +423,12 @@ common_type (t1, t2) parm_done: ; } - return build_function_type (valtype, newargs); + t1 = build_function_type (valtype, newargs); + /* ... falls through ... */ } default: - return t1; + return build_type_attribute_variant (t1, attributes); } } @@ -392,6 +443,7 @@ comptypes (type1, type2) { register tree t1 = type1; register tree t2 = type2; + int attrval, val; /* Suppress errors caused by previously reported errors. */ @@ -427,21 +479,33 @@ comptypes (type1, type2) if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) return 1; +#ifndef COMP_TYPE_ATTRIBUTES +#define COMP_TYPE_ATTRIBUTES(t1,t2) 1 +#endif + + /* 1 if no need for warning yet, 2 if warning cause has been seen. */ + if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2))) + return 0; + + /* 1 if no need for warning yet, 2 if warning cause has been seen. */ + val = 0; + switch (TREE_CODE (t1)) { case POINTER_TYPE: - return (TREE_TYPE (t1) == TREE_TYPE (t2) + val = (TREE_TYPE (t1) == TREE_TYPE (t2) ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2))); + break; case FUNCTION_TYPE: - return function_types_compatible_p (t1, t2); + val = function_types_compatible_p (t1, t2); + break; case ARRAY_TYPE: { - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - int val = 1; tree d1 = TYPE_DOMAIN (t1); tree d2 = TYPE_DOMAIN (t2); + val = 1; /* Target types must match incl. qualifiers. */ if (TREE_TYPE (t1) != TREE_TYPE (t2) @@ -454,24 +518,26 @@ comptypes (type1, type2) || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST) - return val; + break; - return (((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1)) + if (! ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1)) == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2))) && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1)) == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2))) && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1)) == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2))) && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1)) - == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2)))) - ? val : 0); + == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2))))) + val = 0; + break; } case RECORD_TYPE: if (maybe_objc_comptypes (t1, t2, 0) == 1) - return 1; + val = 1; + break; } - return 0; + return attrval == 2 && val == 1 ? 2 : val; } /* Return 1 if TTL and TTR are pointers to types that are equivalent,