diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3899f7e40c5..1ef702c50fe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-11-27 Kenneth Zadeck + + * fold-const.c + (int_const_binop_1): Make INT_MIN % -1 return 0 with the overflow + bit set. + 2013-11-27 Richard Biener PR middle-end/58723 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index d56b35513f6..fcd7f087be8 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1110,7 +1110,22 @@ int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree arg2, case ROUND_MOD_EXPR: if (op2.is_zero ()) return NULL_TREE; - tmp = op1.divmod_with_overflow (op2, uns, code, &res, &overflow); + + /* Check for the case the case of INT_MIN % -1 and return + overflow and result = 0. The TImode case is handled properly + in double-int. */ + if (TYPE_PRECISION (type) <= HOST_BITS_PER_WIDE_INT + && !uns + && op2.is_minus_one () + && op1.high == (HOST_WIDE_INT) -1 + && (HOST_WIDE_INT) op1.low + == (((HOST_WIDE_INT)-1) << (TYPE_PRECISION (type) - 1))) + { + overflow = 1; + res = double_int_zero; + } + else + tmp = op1.divmod_with_overflow (op2, uns, code, &res, &overflow); break; case MIN_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 084e8128dcc..075e0b14d80 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-27 Kenneth Zadeck + + * gcc.dg/c90-const-expr-8.c: Look for overflow on INT_MIN % -1. + * gcc.dg/c99-const-expr-8.c: Look for overflow on INT_MIN % -1. + 2013-11-27 Marek Polacek PR sanitizer/59306 diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-8.c b/gcc/testsuite/gcc.dg/c90-const-expr-8.c index 4923bc68046..b6aba7b1d87 100644 --- a/gcc/testsuite/gcc.dg/c90-const-expr-8.c +++ b/gcc/testsuite/gcc.dg/c90-const-expr-8.c @@ -23,5 +23,6 @@ enum e { /* { dg-error "3:overflow in constant expression" "constant" { target *-*-* } 22 } */ E6 = 0 * !-INT_MIN, /* { dg-warning "13:integer overflow in expression" } */ /* { dg-error "8:not an integer constant" "constant" { target *-*-* } 24 } */ - E7 = INT_MIN % -1 /* Not an overflow. */ + E7 = INT_MIN % -1 /* { dg-warning "16:integer overflow in expression" } */ + /* { dg-error "1:overflow in constant expression" "constant" { target *-*-* } 28 } */ }; diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-8.c b/gcc/testsuite/gcc.dg/c99-const-expr-8.c index e84fa7b4db0..1ddd9ed91ce 100644 --- a/gcc/testsuite/gcc.dg/c99-const-expr-8.c +++ b/gcc/testsuite/gcc.dg/c99-const-expr-8.c @@ -23,5 +23,6 @@ enum e { /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 22 } */ E6 = 0 * !-INT_MIN, /* { dg-warning "integer overflow in expression" } */ /* { dg-error "not an integer constant" "constant" { target *-*-* } 24 } */ - E7 = INT_MIN % -1 /* Not an overflow. */ + E7 = INT_MIN % -1 /* { dg-warning "16:integer overflow in expression" } */ + /* { dg-error "1:overflow in constant expression" "constant" { target *-*-* } 28 } */ };