summaryrefslogtreecommitdiffstats
path: root/gcc/c-typeck.c
diff options
context:
space:
mode:
authormanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-06 16:17:41 +0000
committermanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-06 16:17:41 +0000
commit13869a997eacda65a4fc0cd0176a83290c54a819 (patch)
treea1e568cec33c05d17fd32cf2c3885137e848b1ce /gcc/c-typeck.c
parent8deb3959b001122f1d9f0f8320adc8bc77844046 (diff)
downloadppe42-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.c122
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);
}
}
}
OpenPOWER on IntegriCloud