This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Handle BOOLEAN_TYPEs in c_common_type
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 15 May 2005 22:59:28 -0600 (MDT)
- Subject: [PATCH] Handle BOOLEAN_TYPEs in c_common_type
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
--