Index: fold-const.c =================================================================== --- fold-const.c (revision 105995) +++ fold-const.c (working copy) @@ -4013,8 +4013,22 @@ build_range_check (tree type, tree exp, } } - value = const_binop (MINUS_EXPR, high, low, 0); - if (value != 0 && TREE_OVERFLOW (value) && ! TYPE_UNSIGNED (etype)) + /* Try to build a check for whether EXP - LOW is between zero and + HIGH - LOW. We can only do this safely using an unsigned type, + or when signed values wrap around. Otherwise EXP - LOW might + overflow. And of course it doesn't work if HIGH - LOW + overflows. */ + + value = NULL_TREE; + + if (TYPE_UNSIGNED (type) || flag_wrapv) + { + value = const_binop (MINUS_EXPR, high, low, 0); + if (value && TREE_OVERFLOW (value)) + value = NULL_TREE; + } + + if (value == NULL_TREE && !TYPE_UNSIGNED (type)) { tree utype, minv, maxv; @@ -4025,6 +4039,11 @@ build_range_check (tree type, tree exp, case INTEGER_TYPE: case ENUMERAL_TYPE: case CHAR_TYPE: + /* If we have a type which is a subtype use the + subtype instead. */ + if (TREE_TYPE (etype)) + etype = TREE_TYPE (etype); + utype = lang_hooks.types.unsigned_type (etype); maxv = fold_convert (utype, TYPE_MAX_VALUE (etype)); maxv = range_binop (PLUS_EXPR, NULL_TREE, maxv, 1, @@ -4038,6 +4057,8 @@ build_range_check (tree type, tree exp, low = fold_convert (etype, low); exp = fold_convert (etype, exp); value = const_binop (MINUS_EXPR, high, low, 0); + if (TREE_OVERFLOW (value)) + value = NULL_TREE; } break; default: @@ -4045,7 +4066,7 @@ build_range_check (tree type, tree exp, } } - if (value != 0 && ! TREE_OVERFLOW (value)) + if (value) return build_range_check (type, fold_build2 (MINUS_EXPR, etype, exp, low), 1, fold_convert (etype, integer_zero_node), Index: testsuite/gcc.c-torture/execute/pr22429-1.c =================================================================== --- testsuite/gcc.c-torture/execute/pr22429-1.c (revision 0) +++ testsuite/gcc.c-torture/execute/pr22429-1.c (revision 0) @@ -0,0 +1,14 @@ +int f(int n) +{ + if (-1073741824 <= n && n <= 1073741823) + return 1; + return 0; +} + +int main() +{ + if (f(1073741824)) + abort (); + return 0; +} +