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?

Reply via email to