From c5404f1c2fc79761392acf49af2c46079d907756 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 4 Dec 2015 17:43:53 +0000 Subject: [PATCH] c-common.c (maybe_warn_shift_overflow): Warn on all overflows if shifting 1 out of the sign bit. gcc: 2015-12-04 Paolo Bonzini * c-family/c-common.c (maybe_warn_shift_overflow): Warn on all overflows if shifting 1 out of the sign bit. gcc/testsuite: 2015-12-04 Paolo Bonzini * c-c++-common/Wshift-overflow-1.c: Test shifting 1 out of the sign bit. * c-c++-common/Wshift-overflow-2.c: Test shifting 1 out of the sign bit. * c-c++-common/Wshift-overflow-3.c: Test shifting 1 out of the sign bit. * c-c++-common/Wshift-overflow-4.c: Test shifting 1 out of the sign bit. * c-c++-common/Wshift-overflow-6.c: Test shifting 1 out of the sign bit. * c-c++-common/Wshift-overflow-7.c: Test shifting 1 out of the sign bit. From-SVN: r231290 --- gcc/ChangeLog | 5 +++++ gcc/c-family/c-common.c | 7 +++++-- gcc/testsuite/ChangeLog | 9 +++++++++ gcc/testsuite/c-c++-common/Wshift-overflow-1.c | 5 +++++ gcc/testsuite/c-c++-common/Wshift-overflow-2.c | 5 +++++ gcc/testsuite/c-c++-common/Wshift-overflow-3.c | 5 +++++ gcc/testsuite/c-c++-common/Wshift-overflow-4.c | 5 +++++ gcc/testsuite/c-c++-common/Wshift-overflow-6.c | 1 + gcc/testsuite/c-c++-common/Wshift-overflow-7.c | 1 + 9 files changed, 41 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 572b9a68d84..b25e6430f9b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-12-04 Paolo Bonzini + + * c-family/c-common.c (maybe_warn_shift_overflow): Warn on all + overflows if shifting 1 out of the sign bit. + 2015-12-04 Segher Boessenkool * (cstore4_unsigned): Use gpc_reg_operand instead of diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 381a925331c..f89deb32889 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -12107,8 +12107,11 @@ maybe_warn_shift_overflow (location_t loc, tree op0, tree op1) 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 (min_prec == prec0 + 1) + /* Handle the case of left-shifting 1 into the sign bit. + * However, shifting 1 _out_ of the sign bit, as in + * INT_MIN << 1, is considered an overflow. + */ + if (!tree_int_cst_sign_bit(op0) && min_prec == prec0 + 1) { /* Never warn for C++14 onwards. */ if (cxx_dialect >= cxx14) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2f73100ddaf..e9ad14a12e5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-12-04 Paolo Bonzini + + * c-c++-common/Wshift-overflow-1.c: Test shifting 1 out of the sign bit. + * c-c++-common/Wshift-overflow-2.c: Test shifting 1 out of the sign bit. + * c-c++-common/Wshift-overflow-3.c: Test shifting 1 out of the sign bit. + * c-c++-common/Wshift-overflow-4.c: Test shifting 1 out of the sign bit. + * c-c++-common/Wshift-overflow-6.c: Test shifting 1 out of the sign bit. + * c-c++-common/Wshift-overflow-7.c: Test shifting 1 out of the sign bit. + 2015-11-25 Nick Clifton * gcc.target/msp430/msp_abi_div_funcs.c: New test. diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-1.c b/gcc/testsuite/c-c++-common/Wshift-overflow-1.c index 9969629f2b0..a69f2b83464 100644 --- a/gcc/testsuite/c-c++-common/Wshift-overflow-1.c +++ b/gcc/testsuite/c-c++-common/Wshift-overflow-1.c @@ -8,6 +8,9 @@ #define LLONGM1 (sizeof (long long) * __CHAR_BIT__ - 1) #define LLONGM2 (sizeof (long long) * __CHAR_BIT__ - 2) +#define INT_MIN (-__INT_MAX__-1) +#define LONG_LONG_MIN (-__LONG_LONG_MAX__-1) + int i1 = 1 << INTM1; int i2 = 9 << INTM1; /* { dg-warning "requires 36 bits to represent" } */ int i3 = 10 << INTM2; /* { dg-warning "requires 35 bits to represent" } */ @@ -18,6 +21,7 @@ int i7 = -9 << INTM1; /* { dg-warning "requires 36 bits to represent" } */ int i8 = -10 << INTM2; /* { dg-warning "requires 35 bits to represent" } */ int i9 = -__INT_MAX__ << 2; /* { dg-warning "requires 34 bits to represent" } */ int i10 = -__INT_MAX__ << INTM1; /* { dg-warning "requires 63 bits to represent" } */ +int i11 = INT_MIN << 1; /* { dg-warning "requires 33 bits to represent" } */ int r1 = 1 >> INTM1; int r2 = 9 >> INTM1; @@ -46,6 +50,7 @@ long long int l7 = -9LL << LLONGM1; /* { dg-warning "requires 68 bits to represe long long int l8 = -10LL << LLONGM2; /* { dg-warning "requires 67 bits to represent" } */ long long int l9 = -__LONG_LONG_MAX__ << 2; /* { dg-warning "requires 66 bits to represent" } */ long long int l10 = -__LONG_LONG_MAX__ << LLONGM1; /* { dg-warning "requires 127 bits to represent" } */ +long long int l11 = LONG_LONG_MIN << 1; /* { dg-warning "requires 65 bits to represent" } */ void fn (void) diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-2.c b/gcc/testsuite/c-c++-common/Wshift-overflow-2.c index d5115d01eae..30fd2552df3 100644 --- a/gcc/testsuite/c-c++-common/Wshift-overflow-2.c +++ b/gcc/testsuite/c-c++-common/Wshift-overflow-2.c @@ -8,6 +8,9 @@ #define LLONGM1 (sizeof (long long) * __CHAR_BIT__ - 1) #define LLONGM2 (sizeof (long long) * __CHAR_BIT__ - 2) +#define INT_MIN (-__INT_MAX__-1) +#define LONG_LONG_MIN (-__LONG_LONG_MAX__-1) + int i1 = 1 << INTM1; int i2 = 9 << INTM1; int i3 = 10 << INTM2; @@ -18,6 +21,7 @@ int i7 = -9 << INTM1; int i8 = -10 << INTM2; int i9 = -__INT_MAX__ << 2; int i10 = -__INT_MAX__ << INTM1; +int i11 = INT_MIN << 1; int r1 = 1 >> INTM1; int r2 = 9 >> INTM1; @@ -46,6 +50,7 @@ long long int l7 = -9LL << LLONGM1; long long int l8 = -10LL << LLONGM2; long long int l9 = -__LONG_LONG_MAX__ << 2; long long int l10 = -__LONG_LONG_MAX__ << LLONGM1; +long long int l11 = LONG_LONG_MIN << 1; void fn (void) diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-3.c b/gcc/testsuite/c-c++-common/Wshift-overflow-3.c index ed57d5d8bec..03b07f8092c 100644 --- a/gcc/testsuite/c-c++-common/Wshift-overflow-3.c +++ b/gcc/testsuite/c-c++-common/Wshift-overflow-3.c @@ -9,6 +9,9 @@ #define LLONGM1 (sizeof (long long) * __CHAR_BIT__ - 1) #define LLONGM2 (sizeof (long long) * __CHAR_BIT__ - 2) +#define INT_MIN (-__INT_MAX__-1) +#define LONG_LONG_MIN (-__LONG_LONG_MAX__-1) + int i1 = 1 << INTM1; int i2 = 9 << INTM1; /* { dg-warning "requires 36 bits to represent" } */ int i3 = 10 << INTM2; /* { dg-warning "requires 35 bits to represent" } */ @@ -19,6 +22,7 @@ int i7 = -9 << INTM1; /* { dg-warning "requires 36 bits to represent" } */ int i8 = -10 << INTM2; /* { dg-warning "requires 35 bits to represent" } */ int i9 = -__INT_MAX__ << 2; /* { dg-warning "requires 34 bits to represent" } */ int i10 = -__INT_MAX__ << INTM1; /* { dg-warning "requires 63 bits to represent" } */ +int i11 = INT_MIN << 1; /* { dg-warning "requires 33 bits to represent" } */ int r1 = 1 >> INTM1; int r2 = 9 >> INTM1; @@ -47,6 +51,7 @@ long long int l7 = -9LL << LLONGM1; /* { dg-warning "requires 68 bits to represe long long int l8 = -10LL << LLONGM2; /* { dg-warning "requires 67 bits to represent" } */ long long int l9 = -__LONG_LONG_MAX__ << 2; /* { dg-warning "requires 66 bits to represent" } */ long long int l10 = -__LONG_LONG_MAX__ << LLONGM1; /* { dg-warning "requires 127 bits to represent" } */ +long long int l11 = LONG_LONG_MIN << 1; /* { dg-warning "requires 65 bits to represent" } */ void fn (void) diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-4.c b/gcc/testsuite/c-c++-common/Wshift-overflow-4.c index 92f8cf85b50..d44f9dc9804 100644 --- a/gcc/testsuite/c-c++-common/Wshift-overflow-4.c +++ b/gcc/testsuite/c-c++-common/Wshift-overflow-4.c @@ -9,6 +9,9 @@ #define LLONGM1 (sizeof (long long) * __CHAR_BIT__ - 1) #define LLONGM2 (sizeof (long long) * __CHAR_BIT__ - 2) +#define INT_MIN (-__INT_MAX__-1) +#define LONG_LONG_MIN (-__LONG_LONG_MAX__-1) + int i1 = 1 << INTM1; int i2 = 9 << INTM1; int i3 = 10 << INTM2; @@ -19,6 +22,7 @@ int i7 = -9 << INTM1; int i8 = -10 << INTM2; int i9 = -__INT_MAX__ << 2; int i10 = -__INT_MAX__ << INTM1; +int i11 = INT_MIN << 1; int r1 = 1 >> INTM1; int r2 = 9 >> INTM1; @@ -47,6 +51,7 @@ long long int l7 = -9LL << LLONGM1; long long int l8 = -10LL << LLONGM2; long long int l9 = -__LONG_LONG_MAX__ << 2; long long int l10 = -__LONG_LONG_MAX__ << LLONGM1; +long long int l11 = LONG_LONG_MIN << 1; void fn (void) diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-6.c b/gcc/testsuite/c-c++-common/Wshift-overflow-6.c index d540dea8aae..64797f44a13 100644 --- a/gcc/testsuite/c-c++-common/Wshift-overflow-6.c +++ b/gcc/testsuite/c-c++-common/Wshift-overflow-6.c @@ -34,3 +34,4 @@ int i27 = 0b1000000000000000000000000000 << 4; int i28 = 0b10000000000000000000000000000 << 3; int i29 = 0b100000000000000000000000000000 << 2; int i30 = 0b1000000000000000000000000000000 << 1; +int i31 = (int) 0b10000000000000000000000000000000u << 1; /* { dg-warning "requires 33 bits to represent" } */ diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-7.c b/gcc/testsuite/c-c++-common/Wshift-overflow-7.c index 0eb1fef94c7..ca99d2e46fe 100644 --- a/gcc/testsuite/c-c++-common/Wshift-overflow-7.c +++ b/gcc/testsuite/c-c++-common/Wshift-overflow-7.c @@ -34,3 +34,4 @@ int i27 = 0b1000000000000000000000000000 << 4; /* { dg-warning "requires 33 bits 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" } */ +int i31 = (int) 0b10000000000000000000000000000000u << 1; /* { dg-warning "requires 33 bits to represent" } */ -- 2.30.2