re PR c++/55095 (Wshift-overflow)
authorMarek Polacek <polacek@redhat.com>
Wed, 12 Aug 2015 17:25:23 +0000 (17:25 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 12 Aug 2015 17:25:23 +0000 (17:25 +0000)
PR c++/55095
* c-common.c (maybe_warn_shift_overflow): Properly handle
left-shifting 1 into the sign bit.

* c-c++-common/Wshift-overflow-6.c: New test.
* c-c++-common/Wshift-overflow-7.c: New test.
* g++.dg/cpp1y/left-shift-2.C: New test.

From-SVN: r226826

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wshift-overflow-6.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wshift-overflow-7.c [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/left-shift-2.C [new file with mode: 0644]

index af1f098ac5c757c69dfeb638f0d52bb2f3f0391d..c67c26ce7721b8ded5800ce2a4aa636cd0bbff97 100644 (file)
@@ -1,3 +1,9 @@
+2015-08-12  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/55095
+       * c-common.c (maybe_warn_shift_overflow): Properly handle
+       left-shifting 1 into the sign bit.
+
 2015-08-09  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        * c.opt (Wchkp): Use LangEnabledBy instead of EnabledBy.
index f6c5ddd049618affabd72129bda943e39c04b75b..13175d84f41ce9d12f1a4dfa881ab3fc31757ea5 100644 (file)
@@ -12442,9 +12442,10 @@ maybe_warn_shift_overflow (location_t loc, tree op0, tree op1)
   if (TYPE_UNSIGNED (type0))
     return false;
 
+  unsigned int min_prec = (wi::min_precision (op0, SIGNED)
+                          + TREE_INT_CST_LOW (op1));
   /* Handle the left-shifting 1 into the sign bit case.  */
-  if (integer_onep (op0)
-      && compare_tree_int (op1, prec0 - 1) == 0)
+  if (min_prec == prec0 + 1)
     {
       /* Never warn for C++14 onwards.  */
       if (cxx_dialect >= cxx14)
@@ -12456,8 +12457,6 @@ maybe_warn_shift_overflow (location_t loc, tree op0, tree op1)
        return true;
     }
 
-  unsigned int min_prec = (wi::min_precision (op0, SIGNED)
-                          + TREE_INT_CST_LOW (op1));
   bool overflowed = min_prec > prec0;
   if (overflowed && c_inhibit_evaluation_warnings == 0)
     warning_at (loc, OPT_Wshift_overflow_,
index d18a406ba11618ca589389742b20c7aeafb098ce..0a8679bf8a5dc7b177f11df6451afb644ce1840f 100644 (file)
@@ -1,3 +1,10 @@
+2015-08-12  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/55095
+       * c-c++-common/Wshift-overflow-6.c: New test.
+       * c-c++-common/Wshift-overflow-7.c: New test.
+       * g++.dg/cpp1y/left-shift-2.C: New test.
+
 2015-08-12  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/52742
diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-6.c b/gcc/testsuite/c-c++-common/Wshift-overflow-6.c
new file mode 100644 (file)
index 0000000..d540dea
--- /dev/null
@@ -0,0 +1,36 @@
+/* PR c++/55095 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-Wshift-overflow=1" } */
+/* { dg-additional-options "-std=c++11" { target c++ } } */
+
+int i00 = 0b1 << 31;
+int i01 = 0b10 << 30;
+int i02 = 0b100 << 29;
+int i03 = 0b1000 << 28;
+int i04 = 0b10000 << 27;
+int i05 = 0b100000 << 26;
+int i06 = 0b1000000 << 25;
+int i07 = 0b10000000 << 24;
+int i08 = 0b100000000 << 23;
+int i09 = 0b1000000000 << 22;
+int i10 = 0b10000000000 << 21;
+int i11 = 0b100000000000 << 20;
+int i12 = 0b1000000000000 << 19;
+int i13 = 0b10000000000000 << 18;
+int i14 = 0b100000000000000 << 17;
+int i15 = 0b1000000000000000 << 16;
+int i16 = 0b10000000000000000 << 15;
+int i17 = 0b100000000000000000 << 14;
+int i18 = 0b1000000000000000000 << 13;
+int i19 = 0b10000000000000000000 << 12;
+int i20 = 0b100000000000000000000 << 11;
+int i21 = 0b1000000000000000000000 << 10;
+int i22 = 0b10000000000000000000000 << 9;
+int i23 = 0b100000000000000000000000 << 8;
+int i24 = 0b1000000000000000000000000 << 7;
+int i25 = 0b10000000000000000000000000 << 6;
+int i26 = 0b100000000000000000000000000 << 5;
+int i27 = 0b1000000000000000000000000000 << 4;
+int i28 = 0b10000000000000000000000000000 << 3;
+int i29 = 0b100000000000000000000000000000 << 2;
+int i30 = 0b1000000000000000000000000000000 << 1;
diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-7.c b/gcc/testsuite/c-c++-common/Wshift-overflow-7.c
new file mode 100644 (file)
index 0000000..0eb1fef
--- /dev/null
@@ -0,0 +1,36 @@
+/* PR c++/55095 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-Wshift-overflow=2" } */
+/* { dg-additional-options "-std=c++11" { target c++ } } */
+
+int i00 = 0b1 << 31; /* { dg-warning "requires 33 bits to represent" } */
+int i01 = 0b10 << 30; /* { dg-warning "requires 33 bits to represent" } */
+int i02 = 0b100 << 29; /* { dg-warning "requires 33 bits to represent" } */
+int i03 = 0b1000 << 28; /* { dg-warning "requires 33 bits to represent" } */
+int i04 = 0b10000 << 27; /* { dg-warning "requires 33 bits to represent" } */
+int i05 = 0b100000 << 26; /* { dg-warning "requires 33 bits to represent" } */
+int i06 = 0b1000000 << 25; /* { dg-warning "requires 33 bits to represent" } */
+int i07 = 0b10000000 << 24; /* { dg-warning "requires 33 bits to represent" } */
+int i08 = 0b100000000 << 23; /* { dg-warning "requires 33 bits to represent" } */
+int i09 = 0b1000000000 << 22; /* { dg-warning "requires 33 bits to represent" } */
+int i10 = 0b10000000000 << 21; /* { dg-warning "requires 33 bits to represent" } */
+int i11 = 0b100000000000 << 20; /* { dg-warning "requires 33 bits to represent" } */
+int i12 = 0b1000000000000 << 19; /* { dg-warning "requires 33 bits to represent" } */
+int i13 = 0b10000000000000 << 18; /* { dg-warning "requires 33 bits to represent" } */
+int i14 = 0b100000000000000 << 17; /* { dg-warning "requires 33 bits to represent" } */
+int i15 = 0b1000000000000000 << 16; /* { dg-warning "requires 33 bits to represent" } */
+int i16 = 0b10000000000000000 << 15; /* { dg-warning "requires 33 bits to represent" } */
+int i17 = 0b100000000000000000 << 14; /* { dg-warning "requires 33 bits to represent" } */
+int i18 = 0b1000000000000000000 << 13; /* { dg-warning "requires 33 bits to represent" } */
+int i19 = 0b10000000000000000000 << 12; /* { dg-warning "requires 33 bits to represent" } */
+int i20 = 0b100000000000000000000 << 11; /* { dg-warning "requires 33 bits to represent" } */
+int i21 = 0b1000000000000000000000 << 10; /* { dg-warning "requires 33 bits to represent" } */
+int i22 = 0b10000000000000000000000 << 9; /* { dg-warning "requires 33 bits to represent" } */
+int i23 = 0b100000000000000000000000 << 8; /* { dg-warning "requires 33 bits to represent" } */
+int i24 = 0b1000000000000000000000000 << 7; /* { dg-warning "requires 33 bits to represent" } */
+int i25 = 0b10000000000000000000000000 << 6; /* { dg-warning "requires 33 bits to represent" } */
+int i26 = 0b100000000000000000000000000 << 5; /* { dg-warning "requires 33 bits to represent" } */
+int i27 = 0b1000000000000000000000000000 << 4; /* { dg-warning "requires 33 bits to represent" } */
+int i28 = 0b10000000000000000000000000000 << 3; /* { dg-warning "requires 33 bits to represent" } */
+int i29 = 0b100000000000000000000000000000 << 2; /* { dg-warning "requires 33 bits to represent" } */
+int i30 = 0b1000000000000000000000000000000 << 1; /* { dg-warning "requires 33 bits to represent" } */
diff --git a/gcc/testsuite/g++.dg/cpp1y/left-shift-2.C b/gcc/testsuite/g++.dg/cpp1y/left-shift-2.C
new file mode 100644 (file)
index 0000000..342f907
--- /dev/null
@@ -0,0 +1,36 @@
+// PR c++/55095
+// { dg-do compile { target c++14 } }
+// { dg-options "-Wshift-overflow=2" }
+// { dg-require-effective-target int32 }
+
+int i00 = 0b1 << 31;
+int i01 = 0b10 << 30;
+int i02 = 0b100 << 29;
+int i03 = 0b1000 << 28;
+int i04 = 0b10000 << 27;
+int i05 = 0b100000 << 26;
+int i06 = 0b1000000 << 25;
+int i07 = 0b10000000 << 24;
+int i08 = 0b100000000 << 23;
+int i09 = 0b1000000000 << 22;
+int i10 = 0b10000000000 << 21;
+int i11 = 0b100000000000 << 20;
+int i12 = 0b1000000000000 << 19;
+int i13 = 0b10000000000000 << 18;
+int i14 = 0b100000000000000 << 17;
+int i15 = 0b1000000000000000 << 16;
+int i16 = 0b10000000000000000 << 15;
+int i17 = 0b100000000000000000 << 14;
+int i18 = 0b1000000000000000000 << 13;
+int i19 = 0b10000000000000000000 << 12;
+int i20 = 0b100000000000000000000 << 11;
+int i21 = 0b1000000000000000000000 << 10;
+int i22 = 0b10000000000000000000000 << 9;
+int i23 = 0b100000000000000000000000 << 8;
+int i24 = 0b1000000000000000000000000 << 7;
+int i25 = 0b10000000000000000000000000 << 6;
+int i26 = 0b100000000000000000000000000 << 5;
+int i27 = 0b1000000000000000000000000000 << 4;
+int i28 = 0b10000000000000000000000000000 << 3;
+int i29 = 0b100000000000000000000000000000 << 2;
+int i30 = 0b1000000000000000000000000000000 << 1;