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

Reply via email to