On Wed, Nov 12, 2014 at 11:53:19AM +0100, Richard Biener wrote: > Err - please adjust fold_negate_expr instead.
Like this? (It's not best that for -trapv/-fsanitize=s-i-o we don't emit compile-time warning "integer overflow in expression" for -INT_MIN, because the warning relies on the folding.) Bootstrapped/regtested on power8-linux. 2014-11-14 Marek Polacek <pola...@redhat.com> * fold-const.c (fold_negate_expr): Don't fold INTEGER_CST if that overflows when SANITIZE_SI_OVERFLOW is on. Guard -(-A) folding with TYPE_OVERFLOW_SANITIZED. * c-c++-common/ubsan/overflow-negate-3.c: New test. diff --git gcc/fold-const.c gcc/fold-const.c index ee9ed7b..8994aa4 100644 --- gcc/fold-const.c +++ gcc/fold-const.c @@ -555,7 +555,8 @@ fold_negate_expr (location_t loc, tree t) case INTEGER_CST: tem = fold_negate_const (t, type); if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t) - || !TYPE_OVERFLOW_TRAPS (type)) + || (!TYPE_OVERFLOW_TRAPS (type) + && (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0)) return tem; break; @@ -612,7 +613,9 @@ fold_negate_expr (location_t loc, tree t) break; case NEGATE_EXPR: - return TREE_OPERAND (t, 0); + if (!TYPE_OVERFLOW_SANITIZED (type)) + return TREE_OPERAND (t, 0); + break; case PLUS_EXPR: if (!HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type)) diff --git gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c index e69de29..e6db394 100644 --- gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c +++ gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=signed-integer-overflow" } */ + +#define INT_MIN (-__INT_MAX__ - 1) + +int +main () +{ + int x = INT_MIN; + int y; + asm ("" : "+g" (x)); + y = -(-x); + asm ("" : "+g" (y)); + y = -(-INT_MIN); + asm ("" : "+g" (y)); +} + +/* { dg-output "negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */ Marek