http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56474
--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> 2013-03-04 09:53:39 UTC --- (In reply to comment #4) > This happens because 0 - 1 overflows in sizetype: > > #6 0x0000000000ac3e3d in size_binop_loc (loc=0, code=MINUS_EXPR, > arg0=0x7ffff6d65d60, arg1=0x7ffff6d65f00) > at /home/eric/svn/gcc/gcc/fold-const.c:1417 > 1417 return int_const_binop_1 (code, arg0, arg1, -1); > (gdb) p debug_tree(arg0) > <integer_cst 0x7ffff6d65d60 type <integer_type 0x7ffff6d710a8 sizetype> > constant visited 0> > $28 = void > (gdb) p debug_tree(arg1) > <integer_cst 0x7ffff6d65f00 type <integer_type 0x7ffff6d710a8 sizetype> > constant visited 1> > $29 = void > (gdb) frame 4 > #4 0x0000000000f28804 in force_fit_type_double (type=0x7ffff6d710a8, > cst=..., > overflowable=-1, overflowed=false) at /home/eric/svn/gcc/gcc/tree.c:1109 > 1109 tree t = make_node (INTEGER_CST); > (gdb) p cst > $30 = {low = 18446744073709551615, high = -1} > > Now it didn't overflow on the 4.7 branch: > > Breakpoint 2, int_const_binop (code=MINUS_EXPR, arg1=0x7ffff6d66f00, > arg2=0x7ffff6d790a0) at > /home/eric/svn/gcc-4_7-branch/gcc/fold-const.c:1085 > 1085 return t; > (gdb) p debug_tree(arg1) > <integer_cst 0x7ffff6d66f00 type <integer_type 0x7ffff6d77000 sizetype> > constant visited 0> > $4 = void > (gdb) p debug_tree(arg2) > <integer_cst 0x7ffff6d790a0 type <integer_type 0x7ffff6d77000 sizetype> > constant visited 1> > $5 = void > (gdb) p debug_tree(t) > <integer_cst 0x7ffff6d66f20 type <integer_type 0x7ffff6d77000 sizetype> > constant visited -1> > > This low_bound - 1 idiom is pervasive in Ada and it will probably overflow > only > for 0 so we could add a kludge to size_binop_loc, similarly to the kludge that > exists in layout_type: > > Index: fold-const.c > =================================================================== > --- fold-const.c (revision 196253) > +++ fold-const.c (working copy) > @@ -1389,9 +1389,13 @@ size_binop_loc (location_t loc, enum tre > gcc_assert (int_binop_types_match_p (code, TREE_TYPE (arg0), > TREE_TYPE (arg1))); > > - /* Handle the special case of two integer constants faster. */ > + /* Handle general case of two integer constants. For sizetype constant > + calculations, we always want to know about overflow, even in the > + unsigned case. */ > if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) > { > + int overflowable = -1; > + > /* And some specific cases even faster than that. */ > if (code == PLUS_EXPR) > { > @@ -1404,6 +1408,11 @@ size_binop_loc (location_t loc, enum tre > { > if (integer_zerop (arg1) && !TREE_OVERFLOW (arg1)) > return arg0; > + > + /* ??? We make an exception for 0 - 1 because it's an idiom > + used in length calculations for zero-based arrays. */ > + if (integer_zerop (arg0) && integer_onep (arg1)) > + overflowable = 1; > } > else if (code == MULT_EXPR) > { > @@ -1411,10 +1420,7 @@ size_binop_loc (location_t loc, enum tre > return arg1; > } > > - /* Handle general case of two integer constants. For sizetype > - constant calculations we always want to know about overflow, > - even in the unsigned case. */ > - return int_const_binop_1 (code, arg0, arg1, -1); > + return int_const_binop_1 (code, arg0, arg1, overflowable); > } > > return fold_build2_loc (loc, code, type, arg0, arg1); > > > What do you think Richard? What will the result be used for in this case? The result, usizetype_max, is certainly not 0 - 1 == -1 as it is unsigned. Adding kludges like that might work, but I'd rather try to fix callers to "ask more intelligent questions". That is, + /* ??? We make an exception for 0 - 1 because it's an idiom + used in length calculations for zero-based arrays. */ + if (integer_zerop (arg0) && integer_onep (arg1)) + overflowable = 1; the length of an array is max-index - min-index + 1. What's the call stack of this testcases case triggering the overflow?