re PR sanitizer/81065 (UBSAN: false positive as a result of distribution involving...
authorRichard Biener <rguenther@suse.de>
Tue, 13 Jun 2017 07:07:08 +0000 (07:07 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 13 Jun 2017 07:07:08 +0000 (07:07 +0000)
2017-06-13  Richard Biener  <rguenther@suse.de>

PR middle-end/81065
* fold-const.c (extract_muldiv_1): Remove bogus distribution
case of C * (x * C2 + C3).
(fold_addr_of_array_ref_difference): Properly fold index difference.

* c-c++-common/ubsan/pr81065.c: New testcase.

From-SVN: r249144

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

index 9be291e3d2a28c01132113166c1939def07af22b..f0b9f6b8f34e3e5c633dc9095f65d4c1e041f8b6 100644 (file)
@@ -1,3 +1,10 @@
+2017-06-13  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/81065
+       * fold-const.c (extract_muldiv_1): Remove bogus distribution
+       case of C * (x * C2 + C3).
+       (fold_addr_of_array_ref_difference): Properly fold index difference.
+
 2017-06-12  David S. Miller  <davem@davemloft.net>
 
        PR target/80968
index f3975c7391f6f570beafe5f4bc2ed3db4ce67369..a6dd274f3d2c9be37fee934763dd016fb2b91306 100644 (file)
@@ -6241,11 +6241,6 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
       if (TYPE_UNSIGNED (ctype) && ctype != type)
        break;
 
-      /* If we were able to eliminate our operation from the first side,
-        apply our operation to the second side and reform the PLUS.  */
-      if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR))
-       return fold_build2 (tcode, ctype, fold_convert (ctype, t1), op1);
-
       /* The last case is if we are a multiply.  In that case, we can
         apply the distributive law to commute the multiply and addition
         if the multiplication of the constants doesn't overflow
@@ -8908,7 +8903,7 @@ fold_addr_of_array_ref_difference (location_t loc, tree type,
       tree op0 = fold_convert_loc (loc, type, TREE_OPERAND (aref0, 1));
       tree op1 = fold_convert_loc (loc, type, TREE_OPERAND (aref1, 1));
       tree esz = fold_convert_loc (loc, type, array_ref_element_size (aref0));
-      tree diff = build2 (MINUS_EXPR, type, op0, op1);
+      tree diff = fold_build2_loc (loc, MINUS_EXPR, type, op0, op1);
       return fold_build2_loc (loc, PLUS_EXPR, type,
                              base_offset,
                              fold_build2_loc (loc, MULT_EXPR, type,
index fc941afae3fd9e80a76d8093a1719a664ffceff6..5e9d5ffaef220559896a206d15b0f9fae04e2865 100644 (file)
@@ -1,3 +1,8 @@
+2017-06-13  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/81065
+       * c-c++-common/ubsan/pr81065.c: New testcase.
+
 2017-06-12  Ian Lance Taylor  <iant@golang.org>
 
        * gcc.dg/tree-prof/split-1.c: Require split_stack, don't require
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr81065.c b/gcc/testsuite/c-c++-common/ubsan/pr81065.c
new file mode 100644 (file)
index 0000000..1b34227
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined -fsanitize-undefined-trap-on-error" } */
+
+unsigned char x = 154;
+int foo() {
+  // 8575 * (254408 - 9057) = 8575 * 245351 = 2103884825 = 0x7d66bc19
+  return 8575 * (1652 * x - 9057);
+}
+
+int main() {
+  foo();
+  return 0;
+}