2008-10-29 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
authormanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 Oct 2008 17:16:46 +0000 (17:16 +0000)
committermanu <manu@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 Oct 2008 17:16:46 +0000 (17:16 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141434 138bc75d-0d04-0410-961f-82ee72b054a4

13 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/pr11492.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr11492.c [new file with mode: 0644]
gcc/tree.c
gcc/tree.h

index 1270ebc..dc5ab3b 100644 (file)
@@ -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>
 
        PR middle-end/36578
index 30acb7d..84dea11 100644 (file)
@@ -2795,34 +2795,6 @@ c_register_builtin_type (tree type, const char* name)
 
   registered_builtin_types = tree_cons (0, type, registered_builtin_types);
 }
-
-\f
-/* 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;
-}
 \f
 /* Print an error message for invalid operands to arith operation
    CODE with TYPE0 for operand 0, and TYPE1 for operand 1.
index be38a60..dc5da71 100644 (file)
@@ -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 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.  */
 extern tree c_build_qualified_type (tree, int);
index eba6161..6f88f62 100644 (file)
@@ -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);
       if (!lt
-         || w < 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_min, 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);
     }
 }
@@ -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
      the values are negative.  */
   unsign = (tree_int_cst_sgn (minnode) >= 0);
-  precision = MAX (min_precision (minnode, unsign),
-                  min_precision (maxnode, unsign));
+  precision = MAX (tree_int_cst_min_precision (minnode, unsign),
+                  tree_int_cst_min_precision (maxnode, unsign));
 
   if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
     {
index 5115c1b..8370307 100644 (file)
@@ -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>
 
        PR c++/26997
index 910dc29..31123aa 100644 (file)
@@ -2728,10 +2728,11 @@ check_bitfield_decl (tree field)
        warning (0, "width of %q+D exceeds its type", field);
       else if (TREE_CODE (type) == ENUMERAL_TYPE
               && (0 > compare_tree_int (w,
-                                        min_precision (TYPE_MIN_VALUE (type),
-                                                       TYPE_UNSIGNED (type)))
+                                        tree_int_cst_min_precision
+                                        (TYPE_MIN_VALUE (type),
+                                         TYPE_UNSIGNED (type)))
                   ||  0 > compare_tree_int (w,
-                                            min_precision
+                                            tree_int_cst_min_precision
                                             (TYPE_MAX_VALUE (type),
                                              TYPE_UNSIGNED (type)))))
        warning (0, "%q+D is too small to hold all values of %q#T", field, type);
index b0b03a5..c9cac55 100644 (file)
@@ -10967,11 +10967,11 @@ finish_enum (tree enumtype)
 
   /* Compute the number of bits require to represent all values of the
      enumeration.  We must do this before the type of MINNODE and
-     MAXNODE are transformed, since min_precision relies on the
-     TREE_TYPE of the value it is passed.  */
+     MAXNODE are transformed, since tree_int_cst_min_precision relies
+     on the TREE_TYPE of the value it is passed.  */
   unsignedp = tree_int_cst_sgn (minnode) >= 0;
-  lowprec = min_precision (minnode, unsignedp);
-  highprec = min_precision (maxnode, unsignedp);
+  lowprec = tree_int_cst_min_precision (minnode, unsignedp);
+  highprec = tree_int_cst_min_precision (maxnode, unsignedp);
   precision = MAX (lowprec, highprec);
 
   if (!fixed_underlying_type_p)
index 7a215d2..1a96c3f 100644 (file)
@@ -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
         both unsigned and their total bits is shorter than the result.  */
       if (TREE_CODE (type) == INTEGER_TYPE
-         && TREE_CODE (op0) == NOP_EXPR
-         && TREE_CODE (op1) == NOP_EXPR)
+         && (TREE_CODE (op0) == NOP_EXPR || TREE_CODE (op0) == INTEGER_CST)
+         && (TREE_CODE (op1) == NOP_EXPR || TREE_CODE (op1) == INTEGER_CST))
        {
-         tree inner1 = TREE_TYPE (TREE_OPERAND (op0, 0));
-         tree inner2 = TREE_TYPE (TREE_OPERAND (op1, 0));
-         if (TREE_CODE (inner1) == INTEGER_TYPE && TYPE_UNSIGNED (inner1)
-             && TREE_CODE (inner2) == INTEGER_TYPE && TYPE_UNSIGNED (inner2))
-           return TYPE_PRECISION (inner1) + TYPE_PRECISION (inner2)
-                  < TYPE_PRECISION (type);
+         tree inner0 = (TREE_CODE (op0) == NOP_EXPR) 
+           ? TREE_TYPE (TREE_OPERAND (op0, 0))
+           : TREE_TYPE (op0);
+         tree inner1 = (TREE_CODE (op1) == NOP_EXPR) 
+           ? TREE_TYPE (TREE_OPERAND (op1, 0))
+           : 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;
 
index 6e3f6f2..cee6d6c 100644 (file)
@@ -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>
 
        PR middle-end/36578
diff --git a/gcc/testsuite/g++.dg/warn/pr11492.C b/gcc/testsuite/g++.dg/warn/pr11492.C
new file mode 100644 (file)
index 0000000..d23595f
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.dg/pr11492.c b/gcc/testsuite/gcc.dg/pr11492.c
new file mode 100644 (file)
index 0000000..9d79f45
--- /dev/null
@@ -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;
+}
index 10b50d1..184d247 100644 (file)
@@ -5035,6 +5035,33 @@ tree_int_cst_sgn (const_tree t)
     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
    are known to be equal; otherwise return 0.  */
 
index a85b4c6..d85918f 100644 (file)
@@ -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_sgn (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_warnv_p (tree, bool *);
 extern bool may_negate_without_overflow_p (const_tree);