fold-const.c (fold_negate_expr): Don't fold INTEGER_CST if that overflows when SANITI...
authorMarek Polacek <polacek@redhat.com>
Fri, 14 Nov 2014 11:57:05 +0000 (11:57 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 14 Nov 2014 11:57:05 +0000 (11:57 +0000)
* 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.

From-SVN: r217556

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c [new file with mode: 0644]

index 58efc772d66dea789038b008eee710abad617b95..976dd3bf51dabe3434d54fcbf82853b4310849e8 100644 (file)
@@ -1,3 +1,9 @@
+2014-11-14  Marek Polacek  <polacek@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.
+
 2014-11-14  Marek Polacek  <polacek@redhat.com>
 
        PR sanitizer/63839
index 0170b88daefb69ec7955de5e5560cd4626731ee6..7dbbadd859b30daa2ea910eedbad47fc7fd3ae8d 100644 (file)
@@ -554,7 +554,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;
 
@@ -611,7 +612,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))
index 1d3ef947bf24f90c053b4b2b42efcc86bebab9a4..b6a07d3fb1297d437b9ffce715f52107c9fe330c 100644 (file)
@@ -1,3 +1,7 @@
+2014-11-14  Marek Polacek  <polacek@redhat.com>
+
+       * c-c++-common/ubsan/overflow-negate-3.c: New test.
+
 2014-11-14  Marek Polacek  <polacek@redhat.com>
 
        PR sanitizer/63839
diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c b/gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
new file mode 100644 (file)
index 0000000..e6db394
--- /dev/null
@@ -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)" } */