re PR middle-end/11492 (Bogus warning with -Wsign-compare)
2008-10-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org> PR 11492 * c-common.c (min_precision): Move to... * tree.c (tree_int_cst_min_precision): ... to here. Renamed. * tree.h (tree_int_cst_min_precision): Declare. * c-common.h (min_precision): Delete declaration. * fold-const.c (tree_binary_nonnegative_warnv_p): Handle multiplication of non-negative integer constants. * c-decl.c (check_bitfield_type_and_width): Rename min_precision to tree_int_cst_min_precision. (finish_enum): Likewise. cp/ * class.c (check_bitfield_decl): Rename min_precision to tree_int_cst_min_precision. * decl.c (finish_enum): Likewise. testsuite/ * gcc.dg/pr11492.c: New. * g++.dg/warn/pr11492.C: New. From-SVN: r141434
This commit is contained in:
parent
20ded7a68b
commit
cdd6a337c0
|
@ -1,3 +1,16 @@
|
||||||
|
2008-10-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR 11492
|
||||||
|
* c-common.c (min_precision): Move to...
|
||||||
|
* tree.c (tree_int_cst_min_precision): ... to here. Renamed.
|
||||||
|
* tree.h (tree_int_cst_min_precision): Declare.
|
||||||
|
* c-common.h (min_precision): Delete declaration.
|
||||||
|
* fold-const.c (tree_binary_nonnegative_warnv_p): Handle
|
||||||
|
multiplication of non-negative integer constants.
|
||||||
|
* c-decl.c (check_bitfield_type_and_width): Rename min_precision to
|
||||||
|
tree_int_cst_min_precision.
|
||||||
|
(finish_enum): Likewise.
|
||||||
|
|
||||||
2008-10-29 Joseph Myers <joseph@codesourcery.com>
|
2008-10-29 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
PR middle-end/36578
|
PR middle-end/36578
|
||||||
|
|
|
@ -2795,34 +2795,6 @@ c_register_builtin_type (tree type, const char* name)
|
||||||
|
|
||||||
registered_builtin_types = tree_cons (0, type, registered_builtin_types);
|
registered_builtin_types = tree_cons (0, type, registered_builtin_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return the minimum number of bits needed to represent VALUE in a
|
|
||||||
signed or unsigned type, UNSIGNEDP says which. */
|
|
||||||
|
|
||||||
unsigned int
|
|
||||||
min_precision (tree value, int unsignedp)
|
|
||||||
{
|
|
||||||
int log;
|
|
||||||
|
|
||||||
/* If the value is negative, compute its negative minus 1. The latter
|
|
||||||
adjustment is because the absolute value of the largest negative value
|
|
||||||
is one larger than the largest positive value. This is equivalent to
|
|
||||||
a bit-wise negation, so use that operation instead. */
|
|
||||||
|
|
||||||
if (tree_int_cst_sgn (value) < 0)
|
|
||||||
value = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (value), value);
|
|
||||||
|
|
||||||
/* Return the number of bits needed, taking into account the fact
|
|
||||||
that we need one more bit for a signed than unsigned type. */
|
|
||||||
|
|
||||||
if (integer_zerop (value))
|
|
||||||
log = 0;
|
|
||||||
else
|
|
||||||
log = tree_floor_log2 (value);
|
|
||||||
|
|
||||||
return log + 1 + !unsignedp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print an error message for invalid operands to arith operation
|
/* Print an error message for invalid operands to arith operation
|
||||||
CODE with TYPE0 for operand 0, and TYPE1 for operand 1.
|
CODE with TYPE0 for operand 0, and TYPE1 for operand 1.
|
||||||
|
|
|
@ -746,7 +746,6 @@ extern tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwis
|
||||||
extern tree shorten_compare (tree *, tree *, tree *, enum tree_code *);
|
extern tree shorten_compare (tree *, tree *, tree *, enum tree_code *);
|
||||||
|
|
||||||
extern tree pointer_int_sum (enum tree_code, tree, tree);
|
extern tree pointer_int_sum (enum tree_code, tree, tree);
|
||||||
extern unsigned int min_precision (tree, int);
|
|
||||||
|
|
||||||
/* Add qualifiers to a type, in the fashion for C. */
|
/* Add qualifiers to a type, in the fashion for C. */
|
||||||
extern tree c_build_qualified_type (tree, int);
|
extern tree c_build_qualified_type (tree, int);
|
||||||
|
|
|
@ -3869,8 +3869,8 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
|
||||||
{
|
{
|
||||||
struct lang_type *lt = TYPE_LANG_SPECIFIC (*type);
|
struct lang_type *lt = TYPE_LANG_SPECIFIC (*type);
|
||||||
if (!lt
|
if (!lt
|
||||||
|| w < min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
|
|| w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
|
||||||
|| w < min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
|
|| w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
|
||||||
warning (0, "%qs is narrower than values of its type", name);
|
warning (0, "%qs is narrower than values of its type", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5866,8 +5866,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
|
||||||
that normally we only go as narrow as int - and signed iff any of
|
that normally we only go as narrow as int - and signed iff any of
|
||||||
the values are negative. */
|
the values are negative. */
|
||||||
unsign = (tree_int_cst_sgn (minnode) >= 0);
|
unsign = (tree_int_cst_sgn (minnode) >= 0);
|
||||||
precision = MAX (min_precision (minnode, unsign),
|
precision = MAX (tree_int_cst_min_precision (minnode, unsign),
|
||||||
min_precision (maxnode, unsign));
|
tree_int_cst_min_precision (maxnode, unsign));
|
||||||
|
|
||||||
if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
|
if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2008-10-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR 11492
|
||||||
|
* class.c (check_bitfield_decl): Rename min_precision to
|
||||||
|
tree_int_cst_min_precision.
|
||||||
|
* decl.c (finish_enum): Likewise.
|
||||||
|
|
||||||
2008-10-29 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
2008-10-29 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||||
|
|
||||||
PR c++/26997
|
PR c++/26997
|
||||||
|
|
|
@ -2728,10 +2728,11 @@ check_bitfield_decl (tree field)
|
||||||
warning (0, "width of %q+D exceeds its type", field);
|
warning (0, "width of %q+D exceeds its type", field);
|
||||||
else if (TREE_CODE (type) == ENUMERAL_TYPE
|
else if (TREE_CODE (type) == ENUMERAL_TYPE
|
||||||
&& (0 > compare_tree_int (w,
|
&& (0 > compare_tree_int (w,
|
||||||
min_precision (TYPE_MIN_VALUE (type),
|
tree_int_cst_min_precision
|
||||||
TYPE_UNSIGNED (type)))
|
(TYPE_MIN_VALUE (type),
|
||||||
|
TYPE_UNSIGNED (type)))
|
||||||
|| 0 > compare_tree_int (w,
|
|| 0 > compare_tree_int (w,
|
||||||
min_precision
|
tree_int_cst_min_precision
|
||||||
(TYPE_MAX_VALUE (type),
|
(TYPE_MAX_VALUE (type),
|
||||||
TYPE_UNSIGNED (type)))))
|
TYPE_UNSIGNED (type)))))
|
||||||
warning (0, "%q+D is too small to hold all values of %q#T", field, type);
|
warning (0, "%q+D is too small to hold all values of %q#T", field, type);
|
||||||
|
|
|
@ -10967,11 +10967,11 @@ finish_enum (tree enumtype)
|
||||||
|
|
||||||
/* Compute the number of bits require to represent all values of the
|
/* Compute the number of bits require to represent all values of the
|
||||||
enumeration. We must do this before the type of MINNODE and
|
enumeration. We must do this before the type of MINNODE and
|
||||||
MAXNODE are transformed, since min_precision relies on the
|
MAXNODE are transformed, since tree_int_cst_min_precision relies
|
||||||
TREE_TYPE of the value it is passed. */
|
on the TREE_TYPE of the value it is passed. */
|
||||||
unsignedp = tree_int_cst_sgn (minnode) >= 0;
|
unsignedp = tree_int_cst_sgn (minnode) >= 0;
|
||||||
lowprec = min_precision (minnode, unsignedp);
|
lowprec = tree_int_cst_min_precision (minnode, unsignedp);
|
||||||
highprec = min_precision (maxnode, unsignedp);
|
highprec = tree_int_cst_min_precision (maxnode, unsignedp);
|
||||||
precision = MAX (lowprec, highprec);
|
precision = MAX (lowprec, highprec);
|
||||||
|
|
||||||
if (!fixed_underlying_type_p)
|
if (!fixed_underlying_type_p)
|
||||||
|
|
|
@ -14016,15 +14016,38 @@ tree_binary_nonnegative_warnv_p (enum tree_code code, tree type, tree op0,
|
||||||
/* zero_extend(x) * zero_extend(y) is non-negative if x and y are
|
/* zero_extend(x) * zero_extend(y) is non-negative if x and y are
|
||||||
both unsigned and their total bits is shorter than the result. */
|
both unsigned and their total bits is shorter than the result. */
|
||||||
if (TREE_CODE (type) == INTEGER_TYPE
|
if (TREE_CODE (type) == INTEGER_TYPE
|
||||||
&& TREE_CODE (op0) == NOP_EXPR
|
&& (TREE_CODE (op0) == NOP_EXPR || TREE_CODE (op0) == INTEGER_CST)
|
||||||
&& TREE_CODE (op1) == NOP_EXPR)
|
&& (TREE_CODE (op1) == NOP_EXPR || TREE_CODE (op1) == INTEGER_CST))
|
||||||
{
|
{
|
||||||
tree inner1 = TREE_TYPE (TREE_OPERAND (op0, 0));
|
tree inner0 = (TREE_CODE (op0) == NOP_EXPR)
|
||||||
tree inner2 = TREE_TYPE (TREE_OPERAND (op1, 0));
|
? TREE_TYPE (TREE_OPERAND (op0, 0))
|
||||||
if (TREE_CODE (inner1) == INTEGER_TYPE && TYPE_UNSIGNED (inner1)
|
: TREE_TYPE (op0);
|
||||||
&& TREE_CODE (inner2) == INTEGER_TYPE && TYPE_UNSIGNED (inner2))
|
tree inner1 = (TREE_CODE (op1) == NOP_EXPR)
|
||||||
return TYPE_PRECISION (inner1) + TYPE_PRECISION (inner2)
|
? TREE_TYPE (TREE_OPERAND (op1, 0))
|
||||||
< TYPE_PRECISION (type);
|
: TREE_TYPE (op1);
|
||||||
|
|
||||||
|
bool unsigned0 = TYPE_UNSIGNED (inner0);
|
||||||
|
bool unsigned1 = TYPE_UNSIGNED (inner1);
|
||||||
|
|
||||||
|
if (TREE_CODE (op0) == INTEGER_CST)
|
||||||
|
unsigned0 = unsigned0 || tree_int_cst_sgn (op0) >= 0;
|
||||||
|
|
||||||
|
if (TREE_CODE (op1) == INTEGER_CST)
|
||||||
|
unsigned1 = unsigned1 || tree_int_cst_sgn (op1) >= 0;
|
||||||
|
|
||||||
|
if (TREE_CODE (inner0) == INTEGER_TYPE && unsigned0
|
||||||
|
&& TREE_CODE (inner1) == INTEGER_TYPE && unsigned1)
|
||||||
|
{
|
||||||
|
unsigned int precision0 = (TREE_CODE (op0) == INTEGER_CST)
|
||||||
|
? tree_int_cst_min_precision (op0, /*unsignedp=*/true)
|
||||||
|
: TYPE_PRECISION (inner0);
|
||||||
|
|
||||||
|
unsigned int precision1 = (TREE_CODE (op1) == INTEGER_CST)
|
||||||
|
? tree_int_cst_min_precision (op1, /*unsignedp=*/true)
|
||||||
|
: TYPE_PRECISION (inner1);
|
||||||
|
|
||||||
|
return precision0 + precision1 < TYPE_PRECISION (type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2008-10-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR 11492
|
||||||
|
* gcc.dg/pr11492.c: New.
|
||||||
|
* g++.dg/warn/pr11492.C: New.
|
||||||
|
|
||||||
2008-10-29 Joseph Myers <joseph@codesourcery.com>
|
2008-10-29 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
PR middle-end/36578
|
PR middle-end/36578
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// PR11492
|
||||||
|
// { dg-do compile }
|
||||||
|
// { dg-options "-Wsign-compare" }
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
unsigned int a;
|
||||||
|
unsigned char b;
|
||||||
|
for ( a = 0, b = 2; a > b * 1000; a++ ) /* { dg-bogus "comparison between signed and unsigned integer" } */
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
/* PR11492 */
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-Wsign-compare" } */
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
unsigned int a;
|
||||||
|
unsigned char b;
|
||||||
|
for ( a = 0, b = 2; a > b * 1000; a++ ) /* { dg-bogus "comparison between signed and unsigned integer" } */
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
27
gcc/tree.c
27
gcc/tree.c
|
@ -5035,6 +5035,33 @@ tree_int_cst_sgn (const_tree t)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the minimum number of bits needed to represent VALUE in a
|
||||||
|
signed or unsigned type, UNSIGNEDP says which. */
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
tree_int_cst_min_precision (tree value, bool unsignedp)
|
||||||
|
{
|
||||||
|
int log;
|
||||||
|
|
||||||
|
/* If the value is negative, compute its negative minus 1. The latter
|
||||||
|
adjustment is because the absolute value of the largest negative value
|
||||||
|
is one larger than the largest positive value. This is equivalent to
|
||||||
|
a bit-wise negation, so use that operation instead. */
|
||||||
|
|
||||||
|
if (tree_int_cst_sgn (value) < 0)
|
||||||
|
value = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (value), value);
|
||||||
|
|
||||||
|
/* Return the number of bits needed, taking into account the fact
|
||||||
|
that we need one more bit for a signed than unsigned type. */
|
||||||
|
|
||||||
|
if (integer_zerop (value))
|
||||||
|
log = 0;
|
||||||
|
else
|
||||||
|
log = tree_floor_log2 (value);
|
||||||
|
|
||||||
|
return log + 1 + !unsignedp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compare two constructor-element-type constants. Return 1 if the lists
|
/* Compare two constructor-element-type constants. Return 1 if the lists
|
||||||
are known to be equal; otherwise return 0. */
|
are known to be equal; otherwise return 0. */
|
||||||
|
|
||||||
|
|
|
@ -4022,6 +4022,7 @@ extern HOST_WIDE_INT tree_low_cst (const_tree, int);
|
||||||
extern int tree_int_cst_msb (const_tree);
|
extern int tree_int_cst_msb (const_tree);
|
||||||
extern int tree_int_cst_sgn (const_tree);
|
extern int tree_int_cst_sgn (const_tree);
|
||||||
extern int tree_int_cst_sign_bit (const_tree);
|
extern int tree_int_cst_sign_bit (const_tree);
|
||||||
|
extern unsigned int tree_int_cst_min_precision (tree, bool);
|
||||||
extern bool tree_expr_nonnegative_p (tree);
|
extern bool tree_expr_nonnegative_p (tree);
|
||||||
extern bool tree_expr_nonnegative_warnv_p (tree, bool *);
|
extern bool tree_expr_nonnegative_warnv_p (tree, bool *);
|
||||||
extern bool may_negate_without_overflow_p (const_tree);
|
extern bool may_negate_without_overflow_p (const_tree);
|
||||||
|
|
Loading…
Reference in New Issue