re PR c/56566 (bogus "is narrower than values of its type" warning)
authorJakub Jelinek <jakub@redhat.com>
Mon, 18 Mar 2013 07:10:33 +0000 (08:10 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 18 Mar 2013 07:10:33 +0000 (08:10 +0100)
PR c/56566
* tree.c (tree_int_cst_min_precision): For integer_zerop (value)
return 1 even for !unsignedp.

* c-c++-common/pr56566.c: New test.

From-SVN: r196767

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr56566.c [new file with mode: 0644]
gcc/tree.c

index df6116d36847121e3a4a7187afd23d9501bcd6fb..c91609e89c2991067e121d71e008253eacf45d10 100644 (file)
@@ -1,3 +1,9 @@
+2013-03-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/56566
+       * tree.c (tree_int_cst_min_precision): For integer_zerop (value)
+       return 1 even for !unsignedp.
+
 2013-03-17  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (isa): Add x64 and nox64.
index 0f4a5c4a6dffa34ab9e8d5254f4e1e31758027e4..8f14a53cdb410c0e60cfed99441b931033b90a54 100644 (file)
@@ -1,3 +1,8 @@
+2013-03-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/56566
+       * c-c++-common/pr56566.c: New test.
+
 2013-03-17  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/template/abstract-dr337.C: XFAIL.
diff --git a/gcc/testsuite/c-c++-common/pr56566.c b/gcc/testsuite/c-c++-common/pr56566.c
new file mode 100644 (file)
index 0000000..e753d93
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR c/56566 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct S1 { enum E1 { N1 = -1, Z1 = 0 } e : 1; };
+struct S2 { enum E2 { N2 = -1 } e : 1; };
+struct S3 { enum E3 { Z3 = 0 } e : 1; };
+struct S4 { enum E4 { N4 = -2, Z4 = 1 } e : 2; };
+struct S5 { enum E5 { N5 = -3, Z5 = 1 } e : 3; };
+struct S6 { enum E6 { N6 = -2, Z6 = 1 } e : 1; }; // { dg-warning "too small|narrower" }
+struct S7 { enum E7 { N7 = -3, Z7 = 1 } e : 2; }; // { dg-warning "too small|narrower" }
+struct S8 { enum E8 { Z8 = 1 } e : 1; };
+struct S9 { enum E9 { Z9 = 2 } e : 2; };
+struct S0 { enum E0 { Z0 = 2 } e : 1; };         // { dg-warning "too small|narrower" }
index 98ad5d8784b0078be212087781ce8c061a017a90..31f8037deb89eee560df64d750fb473247a6291a 100644 (file)
@@ -6648,8 +6648,6 @@ tree_int_cst_sgn (const_tree t)
 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
@@ -6659,14 +6657,14 @@ tree_int_cst_min_precision (tree value, bool unsignedp)
     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.  */
+     that we need one more bit for a signed than unsigned type.
+     If value is 0 or -1, the minimum precision is 1 no matter
+     whether unsignedp is true or false.  */
 
   if (integer_zerop (value))
-    log = 0;
+    return 1;
   else
-    log = tree_floor_log2 (value);
-
-  return log + 1 + !unsignedp;
+    return tree_floor_log2 (value) + 1 + !unsignedp;
 }
 
 /* Compare two constructor-element-type constants.  Return 1 if the lists