From: Richard Biener Date: Wed, 23 Sep 2015 14:09:48 +0000 (+0000) Subject: re PR middle-end/67662 (-fsanitize=undefined cries wolf for X - 1 + X when X is 2... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ef537cc859dd149230454398078da6d3128cfd9a;p=gcc.git re PR middle-end/67662 (-fsanitize=undefined cries wolf for X - 1 + X when X is 2**30) 2015-09-23 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a666417cbb9..f6aa3a05f82 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-09-23 Richard Biener + + 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 * config/i386/i386.md (define_insn "*3"): Fix diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c140c62856b..7231fd65d50 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 46d4f053130..759219f62de 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-09-23 Richard Biener + + PR middle-end/67662 + * gcc.dg/ubsan/pr67662.c: New testcase. + 2015-09-23 Manuel López-Ibáñez 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 index 00000000000..26fd00fbbe9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/pr67662.c @@ -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; +}