diff mbox

Fix PR67662

Message ID alpine.LSU.2.11.1509231605250.5289@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Sept. 23, 2015, 2:05 p.m. UTC
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

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.
diff mbox

Patch

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 228037)
+++ gcc/fold-const.c	(working copy)
@@ -9493,25 +9511,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: gcc/testsuite/gcc.dg/ubsan/pr67662.c
===================================================================
--- gcc/testsuite/gcc.dg/ubsan/pr67662.c	(revision 0)
+++ gcc/testsuite/gcc.dg/ubsan/pr67662.c	(working copy)
@@ -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;
+}