re PR c/19342 (ICE in common_type, at c-typeck.c:490)
authorJakub Jelinek <jakub@redhat.com>
Thu, 10 Feb 2005 12:18:52 +0000 (13:18 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 10 Feb 2005 12:18:52 +0000 (13:18 +0100)
PR c/19342
* c-typeck.c (common_type): New routine.  Old common_type renamed
to...
(c_common_type): ...this.
(build_conditional_expr, build_binary_op): Use c_common_type instead
of common_type.

* gcc.c-torture/execute/20050119-1.c: New test.

From-SVN: r94803

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20050119-1.c [new file with mode: 0644]

index 6e14acec2f36cd893bab6f1bbfc425e529d9acc6..dfef24b7a887beb6173f4bd1ecd2d8fc7290d625 100644 (file)
@@ -1,3 +1,12 @@
+2005-02-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/19342
+       * c-typeck.c (common_type): New routine.  Old common_type renamed
+       to...
+       (c_common_type): ...this.
+       (build_conditional_expr, build_binary_op): Use c_common_type instead
+       of common_type.
+
 2005-02-10  Steven Bosscher  <stevenb@suse.de>
 
        * doc/md.texi: Replace @samp{length} with @code{length}.
index f04ba73ad75fe5fa772bea03cc44eb8e423067e8..3a202929e9fc33e2e37b266d34797f4dd43704de 100644 (file)
@@ -470,8 +470,8 @@ common_pointer_type (tree t1, tree t2)
    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)
+static tree
+c_common_type (tree t1, tree t2)
 {
   enum tree_code code1;
   enum tree_code code2;
@@ -522,7 +522,7 @@ common_type (tree t1, tree t2)
     {
       tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
       tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
-      tree subtype = common_type (subtype1, subtype2);
+      tree subtype = c_common_type (subtype1, subtype2);
 
       if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
        return t1;
@@ -592,6 +592,18 @@ common_type (tree t1, tree t2)
     return t2;
 }
 \f
+/* Wrapper around c_common_type that is used by c-common.c.  ENUMERAL_TYPEs
+   are allowed here and are converted to their compatible integer types.  */
+tree
+common_type (tree t1, tree t2)
+{
+  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);
+  return c_common_type (t1, t2);
+}
+\f
 /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
    or various other operations.  Return 2 if they are compatible
    but a warning may be needed if you use them together.  */
@@ -2893,7 +2905,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
            && (code2 == INTEGER_TYPE || code2 == REAL_TYPE
                || code2 == COMPLEX_TYPE))
     {
-      result_type = common_type (type1, type2);
+      result_type = c_common_type (type1, type2);
 
       /* If -Wsign-compare, warn here if type1 and type2 have
         different signedness.  We'll promote the signed to unsigned
@@ -7461,7 +7473,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
       int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
 
       if (shorten || common || short_compare)
-       result_type = common_type (type0, type1);
+       result_type = c_common_type (type0, type1);
 
       /* For certain operations (which identify themselves by shorten != 0)
         if both args were extended from the same smaller type,
@@ -7519,7 +7531,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
              && (unsigned0 || !uns))
            result_type
              = c_common_signed_or_unsigned_type
-             (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
+             (unsigned0, c_common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
          else if (TREE_CODE (arg0) == INTEGER_CST
                   && (unsigned1 || !uns)
                   && (TYPE_PRECISION (TREE_TYPE (arg1))
index e3fe0377147ac0548d2689593b8c682dce566ae8..b73d9472a8d433fa221a0142c067e6bdc14110ac 100644 (file)
@@ -1,3 +1,8 @@
+2005-02-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/19342
+       * gcc.c-torture/execute/20050119-1.c: New test.
+
 2005-02-09  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/19811
diff --git a/gcc/testsuite/gcc.c-torture/execute/20050119-1.c b/gcc/testsuite/gcc.c-torture/execute/20050119-1.c
new file mode 100644 (file)
index 0000000..55f33a0
--- /dev/null
@@ -0,0 +1,37 @@
+/* PR c/19342 */
+typedef enum { A, B, C, D } E;
+
+struct S {
+  E __attribute__ ((mode (__byte__))) a;
+  E __attribute__ ((mode (__byte__))) b;
+  E __attribute__ ((mode (__byte__))) c;
+  E __attribute__ ((mode (__byte__))) d;
+};
+
+extern void abort (void);
+extern void exit (int);
+
+void
+foo (struct S *s)
+{
+  if (s->a != s->b)
+    abort ();
+  if (s->c != C)
+    abort ();
+}
+
+int
+main (void)
+{
+  struct S s[2];
+  s[0].a = B;
+  s[0].b = B;
+  s[0].c = C;
+  s[0].d = D;
+  s[1].a = D;
+  s[1].b = C;
+  s[1].c = B;
+  s[1].d = A;
+  foo (s);
+  exit (0);
+}