re PR middle-end/67662 (-fsanitize=undefined cries wolf for X - 1 + X when X is 2...
authorRichard Biener <rguenther@suse.de>
Wed, 23 Sep 2015 14:09:48 +0000 (14:09 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 23 Sep 2015 14:09:48 +0000 (14:09 +0000)
2015-09-23   Richard Biener  <rguenther@suse.de>

PR middle-end/67662
* fold-const.c (fold_binary_loc): Do not reassociate two vars with
undefined overflow unless they will cancel out.

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

From-SVN: r228051

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ubsan/pr67662.c [new file with mode: 0644]

index a666417cbb9216ab2d8a85c302b070a7dd93c610..f6aa3a05f82a6023efd35cc36f881d1757592a5e 100644 (file)
@@ -1,3 +1,9 @@
+2015-09-23   Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/67662
+       * fold-const.c (fold_binary_loc): Do not reassociate two vars with
+       undefined overflow unless they will cancel out.
+
 2015-09-23  Kirill Yukhin  <kirill.yukhin@intel.com>
 
        * config/i386/i386.md (define_insn "*<mshift><mode>3"): Fix
index c140c62856bb65be5cb9a589b81b2787f1e791aa..7231fd65d50fac7e9efbd6c1969cb06f77d785cd 100644 (file)
@@ -9493,25 +9493,32 @@ fold_binary_loc (location_t loc,
                {
                  tree tmp0 = var0;
                  tree tmp1 = var1;
+                 bool one_neg = false;
 
                  if (TREE_CODE (tmp0) == NEGATE_EXPR)
-                   tmp0 = TREE_OPERAND (tmp0, 0);
+                   {
+                     tmp0 = TREE_OPERAND (tmp0, 0);
+                     one_neg = !one_neg;
+                   }
                  if (CONVERT_EXPR_P (tmp0)
                      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp0, 0)))
                      && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (tmp0, 0)))
                          <= TYPE_PRECISION (atype)))
                    tmp0 = TREE_OPERAND (tmp0, 0);
                  if (TREE_CODE (tmp1) == NEGATE_EXPR)
-                   tmp1 = TREE_OPERAND (tmp1, 0);
+                   {
+                     tmp1 = TREE_OPERAND (tmp1, 0);
+                     one_neg = !one_neg;
+                   }
                  if (CONVERT_EXPR_P (tmp1)
                      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp1, 0)))
                      && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (tmp1, 0)))
                          <= TYPE_PRECISION (atype)))
                    tmp1 = TREE_OPERAND (tmp1, 0);
                  /* The only case we can still associate with two variables
-                    is if they are the same, modulo negation and bit-pattern
-                    preserving conversions.  */
-                 if (!operand_equal_p (tmp0, tmp1, 0))
+                    is if they cancel out.  */
+                 if (!one_neg
+                     || !operand_equal_p (tmp0, tmp1, 0))
                    ok = false;
                }
            }
index 46d4f053130c05eba137a811b4ec9e71f20d0b30..759219f62de647652f4766ad005d24cbfd6d4e50 100644 (file)
@@ -1,3 +1,8 @@
+2015-09-23   Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/67662
+       * gcc.dg/ubsan/pr67662.c: New testcase.
+
 2015-09-23  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        PR c/49655
diff --git a/gcc/testsuite/gcc.dg/ubsan/pr67662.c b/gcc/testsuite/gcc.dg/ubsan/pr67662.c
new file mode 100644 (file)
index 0000000..26fd00f
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined" } */
+
+extern void abort (void);
+
+int
+main (void)
+{
+  int halfmaxval = __INT_MAX__ / 2 + 1;
+  int maxval = halfmaxval - 1 + halfmaxval;
+  if (maxval != __INT_MAX__)
+    abort ();
+  return 0;
+}