This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Avoid potential bogus warnings in the C front-end

Some investigation I've been doing into middle-end clean-up has had
the usual side-effect of exposing a number of latent bugs in the

The following patch fixes a potential bogus diagnostic caused by
c_common_truthvalue_conversion that can result in the failure of
gcc.dg/c99-bool-1.c.  The problem concerns the front-end optimization
of casting a BIT_XOR_EXPR to a bool, thats triggered by the testcase's
use of "u ^= 3" where u is of type _Bool.  The optimization performed
in c_common_truthvalue_conversion is that "(bool)(x ^ y)" can be
rewritten as "x != y".  In the affected testcase, this produces
"(int)u != 3" which the C front-end is clever enough to diagnose as
always true, and generates the warning message:

  comparison is always false due to limited range of data type.

This may be potentially confusing to end-users, as their source
code didn't actually contain any comparison operators!

The proposed solution is to tweak c_common_truthvalue_conversion to
avoid using build_binary_op, which is intended for constructing user
expressions and issuing diagnostics, and instead use fold_build2 which
is the middle-end interface for performing the equivalent optimization
but silently.  The alternate approaches of marking the testcase as
expecting this warning and/or tweaking the C front-end to issue a more
informative/accurate warning are possible, but require more effort.

The following patch has been 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.  The problem is currently
latent but fragile enough to be exposed with changes I'm considering.

Ok for mainline?

2005-05-15  Roger Sayle  <>

	* c-common.c (c_common_truthvalue_conversion): Use fold_build2
	instead of build_binary_op when performing code transformations
	to avoid diagnostics about constructs not it the user's code.

Index: c-common.c
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.628
diff -c -3 -p -r1.628 c-common.c
*** c-common.c	12 May 2005 13:05:52 -0000	1.628
--- c-common.c	15 May 2005 23:16:52 -0000
*************** c_common_truthvalue_conversion (tree exp
*** 2462,2473 ****
  	 two objects.  */
        if (TREE_TYPE (TREE_OPERAND (expr, 0))
  	  == TREE_TYPE (TREE_OPERAND (expr, 1)))
! 	return build_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
! 				TREE_OPERAND (expr, 1), 1);
!       return build_binary_op (NE_EXPR, TREE_OPERAND (expr, 0),
! 			      fold (build1 (NOP_EXPR,
! 					    TREE_TYPE (TREE_OPERAND (expr, 0)),
! 					    TREE_OPERAND (expr, 1))), 1);

      case BIT_AND_EXPR:
        if (integer_onep (TREE_OPERAND (expr, 1))
--- 2462,2473 ----
  	 two objects.  */
        if (TREE_TYPE (TREE_OPERAND (expr, 0))
  	  == TREE_TYPE (TREE_OPERAND (expr, 1)))
! 	return fold_build2 (NE_EXPR, truthvalue_type_node,
! 			    TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
!       return fold_build2 (NE_EXPR, truthvalue_type_node,
! 			  TREE_OPERAND (expr, 0),
! 			  fold_convert (TREE_TYPE (TREE_OPERAND (expr, 0)),
! 					TREE_OPERAND (expr, 1)));

      case BIT_AND_EXPR:
        if (integer_onep (TREE_OPERAND (expr, 1))

Roger Sayle,                         E-mail:
OpenEye Scientific Software,         WWW:
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]