re PR middle-end/63879 (ICE compiling Linux Kernel fs/ext3/namei.c with -fsanitize...
authorMarek Polacek <polacek@redhat.com>
Wed, 19 Nov 2014 12:03:04 +0000 (12:03 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 19 Nov 2014 12:03:04 +0000 (12:03 +0000)
PR sanitizer/63879
* fold-const.c (negate_expr_p) <case NEGATE_EXPR>: Return
!TYPE_OVERFLOW_SANITIZED.
(fold_negate_expr) <case INTEGER_CST>: Fold when overflow
does not trap and when overflow wraps, or when SANITIZE_SI_OVERFLOW
is 0.

* c-c++-common/ubsan/pr63879-1.c: New test.
* c-c++-common/ubsan/pr63879-2.c: New test.

From-SVN: r217766

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/ubsan/pr63879-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/ubsan/pr63879-2.c [new file with mode: 0644]

index a4953e9b63b69dd482019222bd6884b0166e0887..0e9638888d6a91bc53f58336a425d9435ba05dd0 100644 (file)
@@ -1,3 +1,12 @@
+2014-11-19  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/63879
+       * fold-const.c (negate_expr_p) <case NEGATE_EXPR>: Return
+       !TYPE_OVERFLOW_SANITIZED.
+       (fold_negate_expr) <case INTEGER_CST>: Fold when overflow
+       does not trap and when overflow wraps, or when SANITIZE_SI_OVERFLOW
+       is 0.
+
 2014-11-19  Ilya Tocar  <ilya.tocar@intel.com>
 
        * collect2.c (main): Don't call fatal_error before
index f6fb8af8084d875b108754bba37febb1342bedea..9183430205becea5fe90c45a115db000951cadf6 100644 (file)
@@ -408,9 +408,11 @@ negate_expr_p (tree t)
              && TYPE_OVERFLOW_WRAPS (type));
 
     case FIXED_CST:
-    case NEGATE_EXPR:
       return true;
 
+    case NEGATE_EXPR:
+      return !TYPE_OVERFLOW_SANITIZED (type);
+
     case REAL_CST:
       /* We want to canonicalize to positive real constants.  Pretend
          that only negative ones can be easily negated.  */
@@ -555,7 +557,8 @@ fold_negate_expr (location_t loc, tree t)
       tem = fold_negate_const (t, type);
       if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t)
          || (!TYPE_OVERFLOW_TRAPS (type)
-             && (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0))
+             && TYPE_OVERFLOW_WRAPS (type))
+         || (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0)
        return tem;
       break;
 
index 35cb09ce4d3c6d42cf69c10287b0414589c1c395..c3f1bf1e36ffd294e9aaacbb4051c41b27bb741b 100644 (file)
@@ -1,3 +1,9 @@
+2014-11-19  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/63879
+       * c-c++-common/ubsan/pr63879-1.c: New test.
+       * c-c++-common/ubsan/pr63879-2.c: New test.
+
 2014-11-19  Tom de Vries  <tom@codesourcery.com>
 
        PR tree-optimization/62167
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr63879-1.c b/gcc/testsuite/c-c++-common/ubsan/pr63879-1.c
new file mode 100644 (file)
index 0000000..2035849
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR sanitizer/63879 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+struct A
+{
+  int inode;
+} * a;
+int b, c;
+void
+fn1 ()
+{
+  int d = 0;
+  while (b)
+    {
+      if (a->inode)
+        d++;
+      a = 0;
+    }
+  c = d - 1;
+  for (; c >= 0; c--)
+    ;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr63879-2.c b/gcc/testsuite/c-c++-common/ubsan/pr63879-2.c
new file mode 100644 (file)
index 0000000..34eb8e7
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR sanitizer/63879 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+int a;
+void
+fn1 ()
+{
+  int b = 2;
+  for (; a;)
+    while (b >= 0)
+      b--;
+}