aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <merrill@gnu.org>1995-04-01 20:18:49 +0000
committerJason Merrill <merrill@gnu.org>1995-04-01 20:18:49 +0000
commit293c9fdd723d5264c4f2a16bd2072c4952504a91 (patch)
treee98d34cf6a8f771ae0fbbf7c0b373135f456fb11 /gcc
parent2a50a7927541aab0673b8f29757acb58711ffbf5 (diff)
downloadgcc-293c9fdd723d5264c4f2a16bd2072c4952504a91.zip
gcc-293c9fdd723d5264c4f2a16bd2072c4952504a91.tar.gz
gcc-293c9fdd723d5264c4f2a16bd2072c4952504a91.tar.bz2
avoid spurious signed/unsigned comparison warnings.
From-SVN: r9289
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-typeck.c84
1 files changed, 48 insertions, 36 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index e4cfd45..20c653a 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -1897,8 +1897,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
Zero means they need to be converted to RESULT_TYPE. */
int converted = 0;
+ /* Nonzero means create the expression with this type, rather than
+ RESULT_TYPE. */
+ tree build_type = 0;
+
/* Nonzero means after finally constructing the expression
- give it this type. Otherwise, give it type RESULT_TYPE. */
+ convert it to this type. */
tree final_type = 0;
/* Nonzero if this is an operation like MIN or MAX which can
@@ -2169,8 +2173,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
case NE_EXPR:
/* Result of comparison is always int,
but don't convert the args to int! */
- result_type = integer_type_node;
- converted = 1;
+ build_type = integer_type_node;
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
|| code0 == COMPLEX_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
@@ -2201,29 +2204,26 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
}
else
pedwarn ("comparison of distinct pointer types lacks a cast");
+ result_type = common_type (type0, type1);
}
else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
&& integer_zerop (op1))
- op1 = null_pointer_node;
+ result_type = type0;
else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
&& integer_zerop (op0))
- op0 = null_pointer_node;
+ result_type = type1;
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
+ result_type = type0;
if (! flag_traditional)
pedwarn ("comparison between pointer and integer");
- op1 = convert (TREE_TYPE (op0), op1);
}
else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
{
+ result_type = type1;
if (! flag_traditional)
pedwarn ("comparison between pointer and integer");
- op0 = convert (TREE_TYPE (op1), op0);
}
- else
- /* If args are not valid, clear out RESULT_TYPE
- to cause an error message later. */
- result_type = 0;
break;
case MAX_EXPR:
@@ -2246,6 +2246,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
case GE_EXPR:
case LT_EXPR:
case GT_EXPR:
+ build_type = integer_type_node;
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
short_compare = 1;
@@ -2259,39 +2260,34 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
else if (pedantic
&& TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
pedwarn ("ANSI C forbids ordered comparisons of pointers to functions");
- result_type = integer_type_node;
+ result_type = common_type (type0, type1);
}
else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
&& integer_zerop (op1))
{
- result_type = integer_type_node;
- op1 = null_pointer_node;
+ result_type = type0;
if (pedantic)
pedwarn ("ordered comparison of pointer with integer zero");
}
else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
&& integer_zerop (op0))
{
- result_type = integer_type_node;
- op0 = null_pointer_node;
+ result_type = type1;
if (pedantic)
pedwarn ("ordered comparison of pointer with integer zero");
}
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
- result_type = integer_type_node;
+ result_type = type0;
if (! flag_traditional)
pedwarn ("comparison between pointer and integer");
- op1 = convert (TREE_TYPE (op0), op1);
}
else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
{
- result_type = integer_type_node;
+ result_type = type1;
if (! flag_traditional)
pedwarn ("comparison between pointer and integer");
- op0 = convert (TREE_TYPE (op1), op0);
}
- converted = 1;
break;
}
@@ -2433,7 +2429,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
= shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
if (val != 0)
return val;
- op0 = xop0, op1 = xop1, result_type = xresult_type;
+ op0 = xop0, op1 = xop1;
+ converted = 1;
resultcode = xresultcode;
if (extra_warnings)
@@ -2441,8 +2438,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
- tree comp_type = TREE_TYPE (op0);
-
/* Avoid spurious warnings for comparison with enumerators. */
xop0 = orig_op0;
@@ -2451,19 +2446,33 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
STRIP_TYPE_NOPS (xop1);
/* Give warnings for comparisons between signed and unsigned
- quantities that may fail. Do not warn if the signed quantity
- is an unsuffixed integer literal (or some static constant
- expression involving such literals) and it is positive.
- 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. */
+ 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. */
- if (TREE_UNSIGNED (comp_type)
- && ((op0_signed && (TREE_CODE (xop0) != INTEGER_CST
- || tree_int_cst_sgn (xop0) == -1))
- || (op1_signed && (TREE_CODE (xop1) != INTEGER_CST
- || tree_int_cst_sgn (xop1) == -1))))
+
+ /* 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 (! 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 ((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");
}
}
@@ -2489,8 +2498,11 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
op1 = convert (result_type, op1);
}
+ if (build_type == NULL_TREE)
+ build_type = result_type;
+
{
- register tree result = build (resultcode, result_type, op0, op1);
+ register tree result = build (resultcode, build_type, op0, op1);
register tree folded;
folded = fold (result);