From b893e375096038ac99521a97b7fa346b016bdb78 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 12 Aug 2015 17:25:23 +0000 Subject: [PATCH] re PR c++/55095 (Wshift-overflow) 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 | 6 ++++ gcc/c-family/c-common.c | 7 ++-- gcc/testsuite/ChangeLog | 7 ++++ .../c-c++-common/Wshift-overflow-6.c | 36 +++++++++++++++++++ .../c-c++-common/Wshift-overflow-7.c | 36 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp1y/left-shift-2.C | 36 +++++++++++++++++++ 6 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wshift-overflow-6.c create mode 100644 gcc/testsuite/c-c++-common/Wshift-overflow-7.c create mode 100644 gcc/testsuite/g++.dg/cpp1y/left-shift-2.C diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index af1f098ac5c..c67c26ce772 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2015-08-12 Marek Polacek + + 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 * c.opt (Wchkp): Use LangEnabledBy instead of EnabledBy. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index f6c5ddd0496..13175d84f41 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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_, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d18a406ba11..0a8679bf8a5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-08-12 Marek Polacek + + 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 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 index 00000000000..d540dea8aae --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wshift-overflow-6.c @@ -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 index 00000000000..0eb1fef94c7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wshift-overflow-7.c @@ -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 index 00000000000..342f90726ad --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/left-shift-2.C @@ -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; -- 2.30.2