[PATCH] Handle BOOLEAN_TYPEs in c_common_type

Roger Sayle roger@eyesopen.com
Mon May 16 04:59:00 GMT 2005


Another latent bug uncovered by "shaking the tree".

It's (theoretically) possible that c_common_type can be called by
the C front-end with two BOOLEAN_TYPEs.  In the testsuite failure
I was looking at, we had "x != y" where, after shorten_compare has
stripped widening conversions, "x" was of type "_Bool" and y was of
type "bool".  Given these two types aren't identical, the C front-end
calls c_common_type to determine which type to perform the comparison
in, which then fails a gcc_assert as BOOLEAN_TYPE isn't currently
handled in that function.

The following patch enhances c_common_type to correctly/reasonably
handle Boolean types.  These promote to vector, complex and real
types as do integer types.  The common type between an integer and
a Boolean type is the integer type, and the common type between two
Boolean types is the "native" truthvalue_type_node.

Whilst this problem may have been caused by a completely different
latent bug, the fact that the C front-end creates/has more than one
type of class BOOLEAN_TYPE, and the organization of shorten_compare,
means that sooner or later c_common_type may be asked to handle
two Boolean types.


The following patch was tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages, and regression tested with
a top-level "make -k check" with no new failures.

Ok for mainline?



2005-05-15  Roger Sayle  <roger@eyesopen.com>

	* c-typeck.c (c_common_type): Also handle BOOLEAN_TYPEs.


Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.441
diff -c -3 -p -r1.441 c-typeck.c
*** c-typeck.c	10 May 2005 13:46:38 -0000	1.441
--- c-typeck.c	15 May 2005 23:20:07 -0000
*************** c_common_type (tree t1, tree t2)
*** 527,535 ****
    code2 = TREE_CODE (t2);

    gcc_assert (code1 == VECTOR_TYPE || code1 == COMPLEX_TYPE
! 	      || code1 == REAL_TYPE || code1 == INTEGER_TYPE);
    gcc_assert (code2 == VECTOR_TYPE || code2 == COMPLEX_TYPE
! 	      || code2 == REAL_TYPE || code2 == INTEGER_TYPE);

    /* If one type is a vector type, return that type.  (How the usual
       arithmetic conversions apply to the vector types extension is not
--- 527,537 ----
    code2 = TREE_CODE (t2);

    gcc_assert (code1 == VECTOR_TYPE || code1 == COMPLEX_TYPE
! 	      || code1 == REAL_TYPE || code1 == INTEGER_TYPE
! 	      || code1 == BOOLEAN_TYPE);
    gcc_assert (code2 == VECTOR_TYPE || code2 == COMPLEX_TYPE
! 	      || code2 == REAL_TYPE || code2 == INTEGER_TYPE
! 	      || code2 == BOOLEAN_TYPE);

    /* If one type is a vector type, return that type.  (How the usual
       arithmetic conversions apply to the vector types extension is not
*************** c_common_type (tree t1, tree t2)
*** 565,570 ****
--- 567,580 ----
    if (code2 == REAL_TYPE && code1 != REAL_TYPE)
      return t2;

+   /* If only one is bool, use the other as the result.  */
+
+   if (code1 == BOOLEAN_TYPE && code2 != BOOLEAN_TYPE)
+     return t2;
+
+   if (code2 == BOOLEAN_TYPE && code1 != BOOLEAN_TYPE)
+     return t1;
+
    /* Both real or both integers; use the one with greater precision.  */

    if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
*************** c_common_type (tree t1, tree t2)
*** 609,614 ****
--- 619,628 ----
        || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
      return long_double_type_node;

+   /* Prefer the native Boolean type.  */
+   if (code1 == BOOLEAN_TYPE && code2 == BOOLEAN_TYPE)
+     return truthvalue_type_node;
+
    /* Otherwise prefer the unsigned one.  */

    if (TYPE_UNSIGNED (t1))


Roger
--



More information about the Gcc-patches mailing list