diff options
author | manu <manu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-08-06 16:17:41 +0000 |
---|---|---|
committer | manu <manu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-08-06 16:17:41 +0000 |
commit | 13869a997eacda65a4fc0cd0176a83290c54a819 (patch) | |
tree | a1e568cec33c05d17fd32cf2c3885137e848b1ce /gcc/c-typeck.c | |
parent | 8deb3959b001122f1d9f0f8320adc8bc77844046 (diff) | |
download | ppe42-gcc-13869a997eacda65a4fc0cd0176a83290c54a819.tar.gz ppe42-gcc-13869a997eacda65a4fc0cd0176a83290c54a819.zip |
2008-08-06 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 8715
* c-common.c (warn_for_sign_compare): New. Handle separately the
case that 'constant' is zero.
* c-typeck.c (build_binary_op): Move code to c-common.c
cp/
* typeck.c (cp_build_binary_op): Move code to c-common.c.
testsuite/
* gcc.dg/pr8715.c: New.
* g++.dg/warn/pr8715.C: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@138814 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-typeck.c')
-rw-r--r-- | gcc/c-typeck.c | 122 |
1 files changed, 4 insertions, 118 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 4756e256f38..bacff90be02 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -8372,124 +8372,10 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, converted = 1; resultcode = xresultcode; - if (warn_sign_compare && skip_evaluation == 0) - { - int op0_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op0)); - int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1)); - int unsignedp0, unsignedp1; - tree primop0 = get_narrower (op0, &unsignedp0); - tree primop1 = get_narrower (op1, &unsignedp1); - - xop0 = orig_op0; - xop1 = orig_op1; - STRIP_TYPE_NOPS (xop0); - STRIP_TYPE_NOPS (xop1); - - /* Give warnings for comparisons between signed and unsigned - quantities that may fail. - - Do the checking based on the original operand trees, so that - casts will be considered, but default promotions won't be. - - 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)) - /* OK */; - /* Do not warn if both operands are the same signedness. */ - else if (op0_signed == op1_signed) - /* OK */; - else - { - tree sop, uop; - bool ovf; - - if (op0_signed) - sop = xop0, uop = xop1; - else - sop = xop1, uop = xop0; - - /* Do not warn if the signed quantity is an - unsuffixed integer literal (or some static - constant expression involving such literals or a - conditional expression involving such literals) - and it is non-negative. */ - if (tree_expr_nonnegative_warnv_p (sop, &ovf)) - /* OK */; - /* Do not warn if the comparison is an equality operation, - the unsigned quantity is an integral constant, and it - would fit in the result if the result were signed. */ - else if (TREE_CODE (uop) == INTEGER_CST - && (resultcode == EQ_EXPR || resultcode == NE_EXPR) - && int_fits_type_p - (uop, c_common_signed_type (result_type))) - /* OK */; - /* Do not warn if the unsigned quantity is an enumeration - constant and its maximum value would fit in the result - if the result were signed. */ - else if (TREE_CODE (uop) == INTEGER_CST - && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE - && int_fits_type_p - (TYPE_MAX_VALUE (TREE_TYPE (uop)), - c_common_signed_type (result_type))) - /* OK */; - else - warning (OPT_Wsign_compare, "comparison between signed and unsigned"); - } - - /* Warn if two unsigned values are being compared in a size - larger than their original size, and one (and only one) is the - result of a `~' operator. This comparison will always fail. - - Also warn if one operand is a constant, and the constant - does not have all bits set that are set in the ~ operand - when it is extended. */ - - if ((TREE_CODE (primop0) == BIT_NOT_EXPR) - != (TREE_CODE (primop1) == BIT_NOT_EXPR)) - { - if (TREE_CODE (primop0) == BIT_NOT_EXPR) - primop0 = get_narrower (TREE_OPERAND (primop0, 0), - &unsignedp0); - else - primop1 = get_narrower (TREE_OPERAND (primop1, 0), - &unsignedp1); - - if (host_integerp (primop0, 0) || host_integerp (primop1, 0)) - { - tree primop; - HOST_WIDE_INT constant, mask; - int unsignedp, bits; - - if (host_integerp (primop0, 0)) - { - primop = primop1; - unsignedp = unsignedp1; - constant = tree_low_cst (primop0, 0); - } - else - { - primop = primop0; - unsignedp = unsignedp0; - constant = tree_low_cst (primop1, 0); - } - - bits = TYPE_PRECISION (TREE_TYPE (primop)); - if (bits < TYPE_PRECISION (result_type) - && bits < HOST_BITS_PER_WIDE_INT && unsignedp) - { - mask = (~(HOST_WIDE_INT) 0) << bits; - if ((mask & constant) != mask) - warning (OPT_Wsign_compare, "comparison of promoted ~unsigned with constant"); - } - } - else if (unsignedp0 && unsignedp1 - && (TYPE_PRECISION (TREE_TYPE (primop0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (primop1)) - < TYPE_PRECISION (result_type))) - warning (OPT_Wsign_compare, "comparison of promoted ~unsigned with unsigned"); - } + if (warn_sign_compare && !skip_evaluation) + { + warn_for_sign_compare (orig_op0, orig_op1, op0, op1, + result_type, resultcode); } } } |