> >       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);

Reply via email to