[PATCH] Fix PR66313

Richard Biener rguenther@suse.de
Tue Oct 27 14:28:00 GMT 2015


When factoring a*b + a*c to (b + c)*a we have to guard against the
case of a == 0 as after the factoring b + c might overflow in that
case.  Fixed by doing the addition in an unsigned type if required.

Bootstrap / regtest pending on x86_64-unknown-linux-gnu.

Richard.

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

	PR middle-end/66313
	* fold-const.c (fold_plusminus_mult_expr): If the factored
	factor may be zero use a wrapping type for the inner operation.

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

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 229404)
--- gcc/fold-const.c	(working copy)
*************** fold_plusminus_mult_expr (location_t loc
*** 6976,6989 ****
  	}
      }
  
!   if (same)
      return fold_build2_loc (loc, MULT_EXPR, type,
  			fold_build2_loc (loc, code, type,
  				     fold_convert_loc (loc, type, alt0),
  				     fold_convert_loc (loc, type, alt1)),
  			fold_convert_loc (loc, type, same));
  
!   return NULL_TREE;
  }
  
  /* Subroutine of native_encode_expr.  Encode the INTEGER_CST
--- 6989,7016 ----
  	}
      }
  
!   if (!same)
!     return NULL_TREE;
! 
!   if (! INTEGRAL_TYPE_P (type)
!       || TYPE_OVERFLOW_WRAPS (type)
!       || TREE_CODE (same) == INTEGER_CST)
      return fold_build2_loc (loc, MULT_EXPR, type,
  			fold_build2_loc (loc, code, type,
  				     fold_convert_loc (loc, type, alt0),
  				     fold_convert_loc (loc, type, alt1)),
  			fold_convert_loc (loc, type, same));
  
!   /* Same may be zero and thus the operation 'code' may overflow.  Perform
!      the addition in an unsigned type.  */
!   tree utype = unsigned_type_for ( type);
!   return fold_build2_loc (loc, MULT_EXPR, type,
! 			  fold_convert_loc
! 			    (loc, type,
! 			     fold_build2_loc (loc, code, utype,
! 					  fold_convert_loc (loc, utype, alt0),
! 					  fold_convert_loc (loc, utype, alt1))),
! 			  fold_convert_loc (loc, type, same));
  }
  
  /* Subroutine of native_encode_expr.  Encode the INTEGER_CST
Index: gcc/testsuite/c-c++-common/ubsan/pr66313.c
===================================================================
*** gcc/testsuite/c-c++-common/ubsan/pr66313.c	(revision 0)
--- gcc/testsuite/c-c++-common/ubsan/pr66313.c	(working copy)
***************
*** 0 ****
--- 1,12 ----
+ /* { dg-do run } */
+ /* { dg-options "-fsanitize=undefined -fsanitize-undefined-trap-on-error" } */
+ 
+ int __attribute__((noinline,noclone))
+ f(int a, int b, int c)
+ {
+   return a * b + a * c;
+ }
+ int main()
+ {
+   return f(0, __INT_MAX__, __INT_MAX__);
+ }



More information about the Gcc-patches mailing list