From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30583 invoked by alias); 4 Mar 2013 09:53:59 -0000 Received: (qmail 30482 invoked by uid 48); 4 Mar 2013 09:53:41 -0000 From: "rguenth at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug middle-end/56474] [4.8 regression] bogus Storage_Error raised for record containing empty zero-based array Date: Mon, 04 Mar 2013 09:53:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: middle-end X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: rguenth at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: ebotcazou at gcc dot gnu.org X-Bugzilla-Target-Milestone: 4.8.0 X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2013-03/txt/msg00206.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56474 --- Comment #6 from Richard Biener 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) > > constant visited 0> > $28 = void > (gdb) p debug_tree(arg1) > > 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) > > constant visited 0> > $4 = void > (gdb) p debug_tree(arg2) > > constant visited 1> > $5 = void > (gdb) p debug_tree(t) > > 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?