re PR c/35635 (-Wconversion problematic with bitfields)

2008-08-13  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

	PR 35635
	* c-common.c (conversion_warning): Use a switch. Ignore boolean
	expressions except for conversions to signed:1 bitfields. Handle
	COND_EXPR with constant operands.
testsuite/
	* gcc.dg/pr35635.c: New.
	* gcc.dg/Wconversion-integer.c: Update.
	* gcc.dg/Wconversion-integer-no-sign.c: Update.
	* gcc.dg/Wsign-conversion.c: Update.
	* g++.dg/warn/pr35635.C: New.
	* g++.dg/warn/Wconversion-integer.C: Update.
	* g++.dg/warn/Wsign-conversion.C: Update.

From-SVN: r139049
parent 25c6036a
2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 35635
* c-common.c (conversion_warning): Use a switch. Ignore boolean
expressions except for conversions to signed:1 bitfields. Handle
COND_EXPR with constant operands.
2008-08-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/15255
......
......@@ -1559,39 +1559,63 @@ conversion_warning (tree type, tree expr)
{
bool give_warning = false;
unsigned int formal_prec = TYPE_PRECISION (type);
tree expr_type = TREE_TYPE (expr);
if (!warn_conversion && !warn_sign_conversion)
return;
if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST)
switch (TREE_CODE (expr))
{
case EQ_EXPR:
case NE_EXPR:
case LE_EXPR:
case GE_EXPR:
case LT_EXPR:
case GT_EXPR:
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
case TRUTH_NOT_EXPR:
/* Conversion from boolean to a signed:1 bit-field (which only
can hold the values 0 and -1) doesn't lose information - but
it does change the value. */
if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
warning (OPT_Wconversion,
"conversion to %qT from boolean expression", type);
return;
case REAL_CST:
case INTEGER_CST:
/* Warn for real constant that is not an exact integer converted
to integer type. */
if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
if (TREE_CODE (expr_type) == REAL_TYPE
&& TREE_CODE (type) == INTEGER_TYPE)
{
if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (TREE_TYPE (expr))))
if (!real_isinteger (TREE_REAL_CST_PTR (expr), TYPE_MODE (expr_type)))
give_warning = true;
}
/* Warn for an integer constant that does not fit into integer type. */
else if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
else if (TREE_CODE (expr_type) == INTEGER_TYPE
&& TREE_CODE (type) == INTEGER_TYPE
&& !int_fits_type_p (expr, type))
{
if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (TREE_TYPE (expr)))
if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type)
&& tree_int_cst_sgn (expr) < 0)
warning (OPT_Wsign_conversion,
"negative integer implicitly converted to unsigned type");
else if (!TYPE_UNSIGNED (type) && TYPE_UNSIGNED (TREE_TYPE (expr)))
warning (OPT_Wsign_conversion,
"conversion of unsigned constant value to negative integer");
else if (!TYPE_UNSIGNED (type) && TYPE_UNSIGNED (expr_type))
warning (OPT_Wsign_conversion, "conversion of unsigned constant "
"value to negative integer");
else
give_warning = true;
}
else if (TREE_CODE (type) == REAL_TYPE)
{
/* Warn for an integer constant that does not fit into real type. */
if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE)
if (TREE_CODE (expr_type) == INTEGER_TYPE)
{
REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr);
if (!exact_real_truncate (TYPE_MODE (type), &a))
......@@ -1599,8 +1623,8 @@ conversion_warning (tree type, tree expr)
}
/* Warn for a real constant that does not fit into a smaller
real type. */
else if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
&& formal_prec < TYPE_PRECISION (TREE_TYPE (expr)))
else if (TREE_CODE (expr_type) == REAL_TYPE
&& TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
{
REAL_VALUE_TYPE a = TREE_REAL_CST (expr);
if (!exact_real_truncate (TYPE_MODE (type), &a))
......@@ -1611,11 +1635,31 @@ conversion_warning (tree type, tree expr)
if (give_warning)
warning (OPT_Wconversion,
"conversion to %qT alters %qT constant value",
type, TREE_TYPE (expr));
}
else /* 'expr' is not a constant. */
type, expr_type);
return;
case COND_EXPR:
{
tree expr_type = TREE_TYPE (expr);
/* In case of COND_EXPR, if both operands are constants or
COND_EXPR, then we do not care about the type of COND_EXPR,
only about the conversion of each operand. */
tree op1 = TREE_OPERAND (expr, 1);
tree op2 = TREE_OPERAND (expr, 2);
if ((TREE_CODE (op1) == REAL_CST || TREE_CODE (op1) == INTEGER_CST
|| TREE_CODE (op1) == COND_EXPR)
&& (TREE_CODE (op2) == REAL_CST || TREE_CODE (op2) == INTEGER_CST
|| TREE_CODE (op2) == COND_EXPR))
{
conversion_warning (type, op1);
conversion_warning (type, op2);
return;
}
/* Fall through. */
}
default: /* 'expr' is not a constant. */
/* Warn for real types converted to integer types. */
if (TREE_CODE (expr_type) == REAL_TYPE
......@@ -1634,8 +1678,8 @@ conversion_warning (tree type, tree expr)
|| TREE_CODE (expr) == BIT_IOR_EXPR
|| TREE_CODE (expr) == BIT_XOR_EXPR)
{
/* It both args were extended from a shortest type, use
that type if that is safe. */
/* If both args were extended from a shortest type,
use that type if that is safe. */
expr_type = shorten_binary_op (expr_type,
TREE_OPERAND (expr, 0),
TREE_OPERAND (expr, 1),
......@@ -1653,24 +1697,25 @@ conversion_warning (tree type, tree expr)
&& int_fits_type_p (op0, c_common_unsigned_type (type)))
|| (TREE_CODE (op1) == INTEGER_CST
&& int_fits_type_p (op1, c_common_signed_type (type))
&& int_fits_type_p (op1, c_common_unsigned_type (type))))
&& int_fits_type_p (op1,
c_common_unsigned_type (type))))
return;
}
}
/* Warn for integer types converted to smaller integer types. */
if (formal_prec < TYPE_PRECISION (expr_type))
if (TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
give_warning = true;
/* When they are the same width but different signedness,
then the value may change. */
else if ((formal_prec == TYPE_PRECISION (expr_type)
else if ((TYPE_PRECISION (type) == TYPE_PRECISION (expr_type)
&& TYPE_UNSIGNED (expr_type) != TYPE_UNSIGNED (type))
/* Even when converted to a bigger type, if the type is
unsigned but expr is signed, then negative values
will be changed. */
|| (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (expr_type)))
warning (OPT_Wsign_conversion,
"conversion to %qT from %qT may change the sign of the result",
warning (OPT_Wsign_conversion, "conversion to %qT from %qT "
"may change the sign of the result",
type, expr_type);
}
......@@ -1682,8 +1727,10 @@ conversion_warning (tree type, tree expr)
{
tree type_low_bound = TYPE_MIN_VALUE (expr_type);
tree type_high_bound = TYPE_MAX_VALUE (expr_type);
REAL_VALUE_TYPE real_low_bound = real_value_from_int_cst (0, type_low_bound);
REAL_VALUE_TYPE real_high_bound = real_value_from_int_cst (0, type_high_bound);
REAL_VALUE_TYPE real_low_bound
= real_value_from_int_cst (0, type_low_bound);
REAL_VALUE_TYPE real_high_bound
= real_value_from_int_cst (0, type_high_bound);
if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound)
|| !exact_real_truncate (TYPE_MODE (type), &real_high_bound))
......@@ -1693,7 +1740,7 @@ conversion_warning (tree type, tree expr)
/* Warn for real types converted to smaller real types. */
else if (TREE_CODE (expr_type) == REAL_TYPE
&& TREE_CODE (type) == REAL_TYPE
&& formal_prec < TYPE_PRECISION (expr_type))
&& TYPE_PRECISION (type) < TYPE_PRECISION (expr_type))
give_warning = true;
......
2008-08-13 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 35635
* gcc.dg/pr35635.c: New.
* gcc.dg/Wconversion-integer.c: Update.
* gcc.dg/Wconversion-integer-no-sign.c: Update.
* gcc.dg/Wsign-conversion.c: Update.
* g++.dg/warn/pr35635.C: New.
* g++.dg/warn/Wconversion-integer.C: Update.
* g++.dg/warn/Wsign-conversion.C: Update.
2008-08-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/15255
......
......@@ -42,8 +42,8 @@ void h (int x)
uc = x ? 1U : -1; /* { dg-warning "conversion" } */
uc = x ? SCHAR_MIN : 1U; /* { dg-warning "conversion" } */
uc = x ? 1 : -1; /* { dg-warning "conversion" } */
uc = x ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */
uc = x ? 1 : -1; /* Warned by -Wsign-conversion. */
uc = x ? SCHAR_MIN : 1; /* Warned by -Wsign-conversion. */
ui = x ? 1U : -1; /* Warned by -Wsign-conversion. */
ui = x ? INT_MIN : 1U; /* Warned by -Wsign-conversion. */
ui = ui ? SCHAR_MIN : 1U; /* Warned by -Wsign-conversion. */
......
......@@ -42,15 +42,15 @@ void h (int x)
uc = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = x ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = x ? 1 : -1;
uc = x ? SCHAR_MIN : 1;
uc = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = x ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = x ? INT_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = ui ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = 1U * -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = ui + INT_MIN; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = x ? 1 : -1; /* { dg-warning "conversion" } */
ui = ui ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */
ui = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = ui ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
fuc (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
......
/* PR 35635 */
/* { dg-do compile } */
/* { dg-options "-Wconversion -Wsign-conversion" } */
struct unsigned_bit {
unsigned int x:1;
} unsigned_bit;
struct signed_bit {
int x:1;
} signed_bit;
int bar;
int bar2;
void func1()
{
/* The result of boolean operators fits in unsiged int:1, thus do
not warn. */
unsigned_bit.x = (bar != 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar == 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar <= 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar >= 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar < 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar > 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = !bar; /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar || bar2); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar && bar2); /* { dg-bogus "conversion" } */
/* Both branches of ? fit in the destination, thus do not warn. */
unsigned_bit.x = bar != 0 ? 1 : 0; /* { dg-bogus "conversion" } */
unsigned_bit.x = bar != 0 ? 1.0 : 0.0; /* { dg-bogus "conversion" } */
/* At least one branch of ? does not fit in the destination, thus
warn. */
unsigned_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */
unsigned_bit.x = bar != 0 ? 0 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
}
void func2()
{
signed char schar_x;
/* Both branches of ? fit in the destination, thus do not warn. */
schar_x = bar != 0 ? 1 : 0; /* { dg-bogus "conversion" } */
schar_x = bar != 0 ? 2.0 : 10; /* { dg-bogus "conversion" } */
/* At least one branch of ? does not fit in the destination, thus
warn. */
schar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */
schar_x = bar != 0 ? (signed char) 1024: -1024; /* { dg-warning "conversion" } */
}
void func3()
{
unsigned char uchar_x;
/* Both branches of ? fit in the destination, thus do not warn. */
uchar_x = bar != 0 ? 1 : 0;
uchar_x = bar != 0 ? 2.0 : 10;
/* At least one branch of ? does not fit in the destination, thus
warn. */
uchar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */
uchar_x = bar != 0
? (unsigned char) 1024
: -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
}
void func4()
{
signed_bit.x = -1; /* { dg-bogus "conversion" } */
signed_bit.x = bar != 0 ? -1.0 : 0.0; /* { dg-bogus "conversion" } */
signed_bit.x = bar != 0 ? -1 : 0; /* { dg-bogus "conversion" } */
signed_bit.x = 1; /* { dg-warning "conversion" } */
signed_bit.x = (bar != 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar == 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar <= 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar >= 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar < 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar > 0); /* { dg-warning "conversion" } */
signed_bit.x = !bar; /* { dg-warning "conversion" } */
signed_bit.x = (bar || bar2); /* { dg-warning "conversion" } */
signed_bit.x = (bar && bar2); /* { dg-warning "conversion" } */
signed_bit.x = bar != 0 ? 1 : 0; /* { dg-warning "conversion" } */
signed_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */
}
......@@ -42,8 +42,8 @@ void h (int x)
uc = x ? 1U : -1; /* { dg-warning "conversion" } */
uc = x ? SCHAR_MIN : 1U; /* { dg-warning "conversion" } */
uc = x ? 1 : -1; /* { dg-warning "conversion" } */
uc = x ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */
uc = x ? 1 : -1; /* Warned by -Wsign-conversion. */
uc = x ? SCHAR_MIN : 1; /* Warned by -Wsign-conversion. */
ui = x ? 1U : -1; /* Warned by -Wsign-conversion. */
ui = x ? INT_MIN : 1U; /* Warned by -Wsign-conversion. */
ui = ui ? SCHAR_MIN : 1U; /* Warned by -Wsign-conversion. */
......
......@@ -44,15 +44,15 @@ void h (int x)
/* { dg-warning "negative integer implicitly converted to unsigned type" "" { target *-*-* } 43 } */
uc = x ? SCHAR_MIN : 1U; /* { dg-warning "conversion" } */
/* { dg-warning "negative integer implicitly converted to unsigned type" "" { target *-*-* } 45 } */
uc = x ? 1 : -1; /* { dg-warning "conversion" } */
uc = x ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */
uc = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = x ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = x ? INT_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = ui ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = 1U * -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = ui + INT_MIN; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = x ? 1 : -1; /* { dg-warning "conversion" } */
ui = ui ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */
ui = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = ui ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
fuc (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
......
......@@ -42,15 +42,15 @@ void h (int x)
uc = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = x ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = x ? 1 : -1;
uc = x ? SCHAR_MIN : 1;
uc = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = x ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = x ? INT_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = ui ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = 1U * -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = ui + INT_MIN; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = x ? 1 : -1; /* { dg-warning "conversion" } */
ui = ui ? SCHAR_MIN : 1; /* { dg-warning "conversion" } */
ui = x ? 1 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
ui = ui ? SCHAR_MIN : 1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
fuc (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
uc = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
......
/* PR 35635 */
/* { dg-do compile } */
/* { dg-options "-Wconversion -Wsign-conversion" } */
struct unsigned_bit {
unsigned int x:1;
} unsigned_bit;
struct signed_bit {
int x:1;
} signed_bit;
int bar;
int bar2;
void func1()
{
/* The result of boolean operators fits in unsiged int:1, thus do
not warn. */
unsigned_bit.x = (bar != 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar == 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar <= 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar >= 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar < 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar > 0); /* { dg-bogus "conversion" } */
unsigned_bit.x = !bar; /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar || bar2); /* { dg-bogus "conversion" } */
unsigned_bit.x = (bar && bar2); /* { dg-bogus "conversion" } */
/* Both branches of ? fit in the destination, thus do not warn. */
unsigned_bit.x = bar != 0 ? 1 : 0; /* { dg-bogus "conversion" } */
unsigned_bit.x = bar != 0 ? 1.0 : 0.0; /* { dg-bogus "conversion" } */
/* At least one branch of ? does not fit in the destination, thus
warn. */
unsigned_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */
unsigned_bit.x = bar != 0 ? 0 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
}
void func2()
{
signed char schar_x;
/* Both branches of ? fit in the destination, thus do not warn. */
schar_x = bar != 0 ? 1 : 0; /* { dg-bogus "conversion" } */
schar_x = bar != 0 ? 2.0 : 10; /* { dg-bogus "conversion" } */
/* At least one branch of ? does not fit in the destination, thus
warn. */
schar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */
schar_x = bar != 0 ? (signed char) 1024: -1024; /* { dg-warning "conversion" } */
}
void func3()
{
unsigned char uchar_x;
/* Both branches of ? fit in the destination, thus do not warn. */
uchar_x = bar != 0 ? 1 : 0;
uchar_x = bar != 0 ? 2.0 : 10;
/* At least one branch of ? does not fit in the destination, thus
warn. */
uchar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */
uchar_x = bar != 0
? (unsigned char) 1024
: -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
}
void func4()
{
signed_bit.x = -1; /* { dg-bogus "conversion" } */
signed_bit.x = bar != 0 ? -1.0 : 0.0; /* { dg-bogus "conversion" } */
signed_bit.x = bar != 0 ? -1 : 0; /* { dg-bogus "conversion" } */
signed_bit.x = 1; /* { dg-warning "conversion" } */
signed_bit.x = (bar != 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar == 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar <= 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar >= 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar < 0); /* { dg-warning "conversion" } */
signed_bit.x = (bar > 0); /* { dg-warning "conversion" } */
signed_bit.x = !bar; /* { dg-warning "conversion" } */
signed_bit.x = (bar || bar2); /* { dg-warning "conversion" } */
signed_bit.x = (bar && bar2); /* { dg-warning "conversion" } */
signed_bit.x = bar != 0 ? 1 : 0; /* { dg-warning "conversion" } */
signed_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment