[Bug ada/56474] [4.8 regression] bogus Storage_Error raised for record containing empty zero-based array

ebotcazou at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Mar 1 14:26:00 GMT 2013


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56474

--- Comment #4 from Eric Botcazou <ebotcazou at gcc dot gnu.org> 2013-03-01 14:25:56 UTC ---
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?



More information about the Gcc-bugs mailing list