diff options
author | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-05 19:26:23 +0000 |
---|---|---|
committer | zack <zack@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-05 19:26:23 +0000 |
commit | dcf6eb8b028091efbcdd724c03b03633f23bcf0c (patch) | |
tree | 2f5f1a4333cfc525d0e30c2fc974ac8bf2621783 /gcc/c-typeck.c | |
parent | 8fbb495f4658f5554b4f409273eeaf72278683b8 (diff) | |
download | ppe42-gcc-dcf6eb8b028091efbcdd724c03b03633f23bcf0c.tar.gz ppe42-gcc-dcf6eb8b028091efbcdd724c03b03633f23bcf0c.zip |
2000-01-05 11:25 -0800 Zack Weinberg <zack@rabi.columbia.edu>
* c-decl.c (finish_enum): Simplify code to determine minimum and
maximum values of the enum, and calculate the type. Remove check
for FUNCTION_DECLs in the values list, which cannot happen. Replace
the DECL_INITIAL of each enumeration constant with a copy converted
to the enumeration type. When updating variant types, don't bother
updating the type itself.
* c-typeck.c (build_binary_op): Simplify conditional expressions
when weeding out spurious signed-unsigned warnings. Add new
spurious warning category: if the unsigned quantity is an enum
and its maximum value fits in signed_type(result_type). Update
commentary.
(build_conditional_expr): Warn here if one alternative is signed
and the other is unsigned.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31244 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-typeck.c')
-rw-r--r-- | gcc/c-typeck.c | 84 |
1 files changed, 63 insertions, 21 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 8b6a0d69c2a..0529d2a5b18 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -2390,8 +2390,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) tree primop0 = get_narrower (op0, &unsignedp0); tree primop1 = get_narrower (op1, &unsignedp1); - /* Avoid spurious warnings for comparison with enumerators. */ - xop0 = orig_op0; xop1 = orig_op1; STRIP_TYPE_NOPS (xop0); @@ -2407,28 +2405,41 @@ build_binary_op (code, orig_op0, orig_op1, convert_p) all the values of the unsigned type. */ if (! TREE_UNSIGNED (result_type)) /* OK */; - /* Do not warn if both operands are unsigned. */ + /* Do not warn if both operands are the same signedness. */ else if (op0_signed == op1_signed) /* OK */; - /* Do not warn if the signed quantity is an unsuffixed - integer literal (or some static constant expression - involving such literals) and it is non-negative. */ - else if ((op0_signed && TREE_CODE (xop0) == INTEGER_CST - && tree_int_cst_sgn (xop0) >= 0) - || (op1_signed && TREE_CODE (xop1) == INTEGER_CST - && tree_int_cst_sgn (xop1) >= 0)) - /* OK */; - /* Do not warn if the comparison is an equality operation, - the unsigned quantity is an integral constant and it does - not use the most significant bit of result_type. */ - else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR) - && ((op0_signed && TREE_CODE (xop1) == INTEGER_CST - && int_fits_type_p (xop1, signed_type (result_type))) - || (op1_signed && TREE_CODE (xop0) == INTEGER_CST - && int_fits_type_p (xop0, signed_type (result_type))))) - /* OK */; else - warning ("comparison between signed and unsigned"); + { + tree sop, uop; + 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) and it is non-negative. */ + if (TREE_CODE (sop) == INTEGER_CST + && tree_int_cst_sgn (sop) >= 0) + /* 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, 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)), + signed_type (result_type))) + /* OK */; + else + warning ("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 @@ -3362,6 +3373,37 @@ build_conditional_expr (ifexp, op1, op2) && (code2 == INTEGER_TYPE || code2 == REAL_TYPE)) { result_type = common_type (type1, type2); + + /* If -Wsign-compare, warn here if type1 and type2 have + different signedness. We'll promote the signed to unsigned + and later code won't know it used to be different. + Do this check on the original types, so that explicit casts + will be considered, but default promotions won't. */ + if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare) + && !skip_evaluation) + { + int unsigned_op1 = TREE_UNSIGNED (TREE_TYPE (orig_op1)); + int unsigned_op2 = TREE_UNSIGNED (TREE_TYPE (orig_op2)); + + if (unsigned_op1 ^ unsigned_op2) + { + /* Do not warn if the result type is signed, since the + signed type will only be chosen if it can represent + all the values of the unsigned type. */ + if (! TREE_UNSIGNED (result_type)) + /* OK */; + /* Do not warn if the signed quantity is an unsuffixed + integer literal (or some static constant expression + involving such literals) and it is non-negative. */ + else if ((unsigned_op2 && TREE_CODE (op1) == INTEGER_CST + && tree_int_cst_sgn (op1) >= 0) + || (unsigned_op1 && TREE_CODE (op2) == INTEGER_CST + && tree_int_cst_sgn (op2) >= 0)) + /* OK */; + else + warning ("signed and unsigned type in conditional expression"); + } + } } else if (code1 == VOID_TYPE || code2 == VOID_TYPE) { |