The following valid code snippet triggers an ICE since GCC 4.0.0 when compiled with "-W": ================================ void foo(__complex__ int i) { i == 0u; } ================================ bug.c: In function 'foo': bug.c:3: internal compiler error: tree check: expected integer_type or enumeral_type or boolean_type or real_type or fixed_point_type, have complex_type in int_fits_type_p, at tree.c:6173 Please submit a full bug report, [etc.]
This is a front-end issue. C++ calls it at: 3952 /* Do not warn if the comparison is an equality operation, 3953 the unsigned quantity is an integral constant and it does 3954 not use the most significant bit of result_type. */ 3955 else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR) 3956 && ((op0_signed && TREE_CODE (orig_op1) == INTEGER_CST 3957 && int_fits_type_p (orig_op1, c_common_signed_type 3958 (result_type))) While C does: 8499 /* Do not warn if the comparison is an equality operation, 8500 the unsigned quantity is an integral constant, and it 8501 would fit in the result if the result were signed. */ 8502 else if (TREE_CODE (uop) == INTEGER_CST 8503 && (resultcode == EQ_EXPR || resultcode == NE_EXPR) 8504 && int_fits_type_p 8505 (uop, c_common_signed_type (result_type)))
I am going to fix this bug but not until tonight.
This is the patch which I am testing: Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 133711) +++ cp/typeck.c (working copy) @@ -3917,6 +3917,10 @@ cp_build_binary_op (enum tree_code code, int unsignedp0, unsignedp1; tree primop0 = get_narrower (op0, &unsignedp0); tree primop1 = get_narrower (op1, &unsignedp1); + tree undertype = result_type; + + if (TREE_CODE (undertype) == COMPLEX_TYPE) + undertype = TREE_TYPE (undertype); /* Check for comparison of different enum types. */ if (TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE @@ -3937,7 +3941,7 @@ cp_build_binary_op (enum tree_code code, /* Do not warn if the comparison is being done in a signed type, since the signed type will only be chosen if it can represent all the values of the unsigned type. */ - if (!TYPE_UNSIGNED (result_type)) + if (!TYPE_UNSIGNED (undertype)) /* OK */; /* Do not warn if both operands are unsigned. */ else if (op0_signed == op1_signed) @@ -3955,10 +3959,10 @@ cp_build_binary_op (enum tree_code code, else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR) && ((op0_signed && TREE_CODE (orig_op1) == INTEGER_CST && int_fits_type_p (orig_op1, c_common_signed_type - (result_type))) + (undertype))) || (op1_signed && TREE_CODE (orig_op0) == INTEGER_CST && int_fits_type_p (orig_op0, c_common_signed_type - (result_type))))) + (undertype))))) /* OK */; else if (complain & tf_warning) warning (OPT_Wsign_compare, Index: c-typeck.c =================================================================== --- c-typeck.c (revision 133711) +++ c-typeck.c (working copy) @@ -8483,6 +8483,9 @@ build_binary_op (enum tree_code code, tr { tree sop, uop; bool ovf; + tree undertype = result_type; + if (TREE_CODE (undertype) == COMPLEX_TYPE) + undertype = TREE_TYPE (undertype); if (op0_signed) sop = xop0, uop = xop1; @@ -8502,7 +8505,7 @@ build_binary_op (enum tree_code code, tr else if (TREE_CODE (uop) == INTEGER_CST && (resultcode == EQ_EXPR || resultcode == NE_EXPR) && int_fits_type_p - (uop, c_common_signed_type (result_type))) + (uop, c_common_signed_type (undertype))) /* OK */; /* Do not warn if the unsigned quantity is an enumeration constant and its maximum value would fit in the result @@ -8511,7 +8514,7 @@ build_binary_op (enum tree_code code, tr && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (uop)), - c_common_signed_type (result_type))) + c_common_signed_type (undertype))) /* OK */; else warning (OPT_Wsign_compare, "comparison between signed and unsigned");
Closing 4.1 branch.
Subject: Bug 35430 Author: jakub Date: Tue Nov 4 20:51:38 2008 New Revision: 141587 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141587 Log: PR c/35430 * c-common.c (warn_for_sign_compare): For complex result_type use component's type. * gcc.dg/pr35430.c: New test. * g++.dg/warn/Wsign-compare-2.C: New test. Added: trunk/gcc/testsuite/g++.dg/warn/Wsign-compare-2.C trunk/gcc/testsuite/gcc.dg/pr35430.c Modified: trunk/gcc/ChangeLog trunk/gcc/c-common.c trunk/gcc/testsuite/ChangeLog
Fixed on the trunk.
Closing 4.2 branch.
I am no longer working on this one.
GCC 4.3.4 is being released, adjusting target milestone.
WONTFIX on the 4.3 branch.