[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