diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-09-23 14:09:48 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-09-23 14:09:48 +0000 |
commit | 6c1bd04c3bac12d73baa19d45a13bbf7058ee3ad (patch) | |
tree | 67581402c59ae589386b720bd313c301e37ab859 | |
parent | 7013cc711fad7d1186dadc1ab09680bf48da0f4d (diff) | |
download | gcc-6c1bd04c3bac12d73baa19d45a13bbf7058ee3ad.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@228051 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ubsan/pr67662.c | 14 |
4 files changed, 37 insertions, 5 deletions
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 <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 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 <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 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; +} |