This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR68142


This avoids simplifying 2 * (a * (__INT_MAX__/2 + 1))
to a * INT_MIN which introduces undefined overflow for a == -1.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-10-29  Richard Biener  <rguenther@suse.de>

	PR middle-end/68142
	* fold-const.c (extract_muldiv_1): Avoid introducing undefined
	overflow.

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

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 229517)
--- gcc/fold-const.c	(working copy)
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 6008,6015 ****
  	 or (for divide and modulus) if it is a multiple of our constant.  */
        if (code == MULT_EXPR
  	  || wi::multiple_of_p (t, c, TYPE_SIGN (type)))
! 	return const_binop (code, fold_convert (ctype, t),
! 			    fold_convert (ctype, c));
        break;
  
      CASE_CONVERT: case NON_LVALUE_EXPR:
--- 6015,6031 ----
  	 or (for divide and modulus) if it is a multiple of our constant.  */
        if (code == MULT_EXPR
  	  || wi::multiple_of_p (t, c, TYPE_SIGN (type)))
! 	{
! 	  tree tem = const_binop (code, fold_convert (ctype, t),
! 				  fold_convert (ctype, c));
! 	  /* If the multiplication overflowed to INT_MIN then we lost sign
! 	     information on it and a subsequent multiplication might
! 	     spuriously overflow.  See PR68142.  */
! 	  if (TREE_OVERFLOW (tem)
! 	      && wi::eq_p (tem, wi::min_value (TYPE_PRECISION (ctype), SIGNED)))
! 	    return NULL_TREE;
! 	  return tem;
! 	}
        break;
  
      CASE_CONVERT: case NON_LVALUE_EXPR:
Index: gcc/testsuite/c-c++-common/ubsan/pr68142.c
===================================================================
*** gcc/testsuite/c-c++-common/ubsan/pr68142.c	(revision 0)
--- gcc/testsuite/c-c++-common/ubsan/pr68142.c	(working copy)
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-do run } */
+ /* { dg-options "-fsanitize=undefined -fsanitize-undefined-trap-on-error" } */
+ 
+ int __attribute__((noinline,noclone))
+ h(int a)
+ {
+   return 2 * (a * (__INT_MAX__/2 + 1));
+ }
+ int __attribute__((noinline,noclone))
+ i(int a)
+ {
+   return (2 * a) * (__INT_MAX__/2 + 1);
+ }
+ int __attribute__((noinline,noclone))
+ j(int a, int b)
+ {
+   return (b * a) * (__INT_MAX__/2 + 1);
+ }
+ int __attribute__((noinline,noclone))
+ k(int a, int b)
+ {
+   return (2 * a) * b;
+ }
+ int main()
+ {
+   volatile int tem = h(-1);
+   tem = i(-1);
+   tem = j(-1, 2);
+   tem = k(-1, __INT_MAX__/2 + 1);
+   return 0;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]