> > if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node) > > || same_type_p (TYPE_MAIN_VARIANT (t2), > > long_long_unsigned_type_node)) > > return build_type_attribute_variant (long_long_unsigned_type_node, > > attributes); > > Your patch only compares t1/t2 to int_n_trees[i].signed_type.
Checking the code before this logic, we can make some assumptions: /* Both real or both integers; use the one with greater precision. */ * we can assume the two types have the same precision /* The types are the same; no need to do anything fancy. */ * we can assume the two types are different In the case of non-128 __intN, checking only for signed *should* work - the only other type that's the same precision but a different type *is* the unsigned variant (enforced in toplev.c). Even in the case of __int128, if either type is signed __int128 and the other type is different AT ALL, the result will be unsigned __int128 if either type is unsigned, or signed __int128. But a new patch which checks everything anyway is attached :-) Index: typeck.c =================================================================== --- typeck.c (revision 216012) +++ typeck.c (working copy) @@ -270,6 +270,7 @@ enum tree_code code1 = TREE_CODE (t1); enum tree_code code2 = TREE_CODE (t2); tree attributes; + int i; /* In what follows, we slightly generalize the rules given in [expr] so @@ -364,17 +365,6 @@ : long_long_integer_type_node); return build_type_attribute_variant (t, attributes); } - if (int128_integer_type_node != NULL_TREE - && (same_type_p (TYPE_MAIN_VARIANT (t1), - int128_integer_type_node) - || same_type_p (TYPE_MAIN_VARIANT (t2), - int128_integer_type_node))) - { - tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2)) - ? int128_unsigned_type_node - : int128_integer_type_node); - return build_type_attribute_variant (t, attributes); - } /* Go through the same procedure, but for longs. */ if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node) @@ -388,6 +378,26 @@ ? long_unsigned_type_node : long_integer_type_node); return build_type_attribute_variant (t, attributes); } + + /* For __intN types, either the type is __int128 (and is lower + priority than the types checked above, but higher than other + 128-bit types) or it's known to not be the same size as other + types (enforced in toplev.c). Prefer the unsigned type. */ + for (i = 0; i < NUM_INT_N_ENTS; i ++) + { + if (int_n_enabled_p [i] + && (same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].signed_type) + || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].signed_type) + || same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].unsigned_type) + || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].unsigned_type))) + { + tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2)) + ? int_n_trees[i].unsigned_type + : int_n_trees[i].signed_type); + return build_type_attribute_variant (t, attributes); + } + } + /* Otherwise prefer the unsigned one. */ if (TYPE_UNSIGNED (t1)) return build_type_attribute_variant (t1, attributes);