This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR56956
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Oct 2015 09:21:00 +0100 (CET)
- Subject: [PATCH] Fix PR56956
- Authentication-results: sourceware.org; auth=none
This avoids introducing undefined overflow by not folding
unsigned conditional negation to ABS_EXPR. IMHO we want a
well-defined ABS_EXPR with unsigned result at some point, but that
also needs target support (or auditing at least if we want to keep
the existing abs expanders).
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
2015-10-29 Richard Biener <rguenther@suse.de>
PR middle-end/56956
* fold-const.c (fold_cond_expr_with_comparison): Do not fold
unsigned conditonal negation to ABS_EXPR.
* c-c++-common/ubsan/pr56956.c: New testcase.
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c (revision 229481)
--- gcc/fold-const.c (working copy)
*************** fold_cond_expr_with_comparison (location
*** 4993,5000 ****
case GE_EXPR:
case GT_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
! arg1 = fold_convert_loc (loc, signed_type_for
! (TREE_TYPE (arg1)), arg1);
tem = fold_build1_loc (loc, ABS_EXPR, TREE_TYPE (arg1), arg1);
return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, tem));
case UNLE_EXPR:
--- 4973,4979 ----
case GE_EXPR:
case GT_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
! break;
tem = fold_build1_loc (loc, ABS_EXPR, TREE_TYPE (arg1), arg1);
return pedantic_non_lvalue_loc (loc, fold_convert_loc (loc, type, tem));
case UNLE_EXPR:
*************** fold_cond_expr_with_comparison (location
*** 5004,5011 ****
case LE_EXPR:
case LT_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
! arg1 = fold_convert_loc (loc, signed_type_for
! (TREE_TYPE (arg1)), arg1);
tem = fold_build1_loc (loc, ABS_EXPR, TREE_TYPE (arg1), arg1);
return negate_expr (fold_convert_loc (loc, type, tem));
default:
--- 4983,4989 ----
case LE_EXPR:
case LT_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
! break;
tem = fold_build1_loc (loc, ABS_EXPR, TREE_TYPE (arg1), arg1);
return negate_expr (fold_convert_loc (loc, type, tem));
default:
Index: gcc/testsuite/c-c++-common/ubsan/pr56956.c
===================================================================
*** gcc/testsuite/c-c++-common/ubsan/pr56956.c (revision 0)
--- gcc/testsuite/c-c++-common/ubsan/pr56956.c (working copy)
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do run } */
+ /* { dg-options "-fsanitize=undefined -fsanitize-undefined-trap-on-error" } */
+
+ unsigned int __attribute__((noinline,noclone))
+ foo (unsigned int x)
+ {
+ return x <= __INT_MAX__ ? x : -x;
+ }
+
+ int
+ main ()
+ {
+ volatile unsigned int tem = foo (-__INT_MAX__ - 1);
+ return 0;
+ }