This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR68142
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Oct 2015 15:09:12 +0100 (CET)
- Subject: [PATCH] Fix PR68142
- Authentication-results: sourceware.org; auth=none
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;
+ }