The following makes fold_neagte_const properly handle TREE_OVERFLOW as
sticky (even if present on POINTER_TYPE constants).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2017-06-25  Richard Biener  <rguent...@suse.de>

        PR middle-end/81505
        * fold-const.c (fold_negate_const): TREE_OVERFLOW should be
        sticky.

        * gcc.dg/ubsan/pr81505.c: New testcase.

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 250386)
+++ gcc/fold-const.c    (working copy)
@@ -13693,8 +13693,8 @@ fold_negate_const (tree arg0, tree type)
        bool overflow;
        wide_int val = wi::neg (arg0, &overflow);
        t = force_fit_type (type, val, 1,
-                           (overflow | TREE_OVERFLOW (arg0))
-                           && !TYPE_UNSIGNED (type));
+                           (overflow && ! TYPE_UNSIGNED (type))
+                           || TREE_OVERFLOW (arg0));
        break;
       }
 
Index: gcc/testsuite/gcc.dg/ubsan/pr81505.c
===================================================================
--- gcc/testsuite/gcc.dg/ubsan/pr81505.c        (nonexistent)
+++ gcc/testsuite/gcc.dg/ubsan/pr81505.c        (working copy)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fsanitize=signed-integer-overflow" } */
+
+int a, b, c, h;
+
+int i[5][5];
+
+void
+fn1 ()
+{
+  int l = 0;
+
+  for (a = 0; a <= 3; a++)
+    for (b = 1; b >= 0; b -= 1)
+      l |= i[0][b];
+  c = l;
+}

Reply via email to