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 PR56956


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;
+ }


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