Hi,
this is a regression present on the mainline and 4.8 branch and introduced by
the latest series of sizetype changes. Associated adjustments were made in
the various front-ends for it, most notably Ada which was the most affected,
but this issue slipped through the cracks in the form of a bogus overflow
detection for 0-based arrays with variable upper bound included in a record
with discriminant.
The proposed fix is to disable overflow detection in sizetype for one special
case (0 - 1) in size_binop_loc. An equivalent kludge was added to layout_type
to disable overflow detection for the size expression of [0, -1] arrays.
Tested on x86_64-suse-linux, OK for the mainline and 4.8 branch?
2013-04-14 Eric Botcazou <ebotca...@adacore.com>
PR middle-end/56474
* fold-const.c (size_binop_loc): Disable overflow detection for 0 - 1.
2013-04-14 Eric Botcazou <ebotca...@adacore.com>
* gnat.dg/specs/array3.ads: New test.
--
Eric Botcazou
Index: fold-const.c
===================================================================
--- fold-const.c (revision 197926)
+++ fold-const.c (working copy)
@@ -1422,9 +1422,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)
{
@@ -1437,6 +1441,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)
{
@@ -1444,10 +1453,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);
-- PR middle-end/56474
-- Reported by Pavel Zhukov <pa...@zhukoff.net>
-- { dg-do compile }
with Ada.Streams;
package Array3 is
use type Ada.Streams.Stream_Element_Offset;
type Vector (Size : Ada.Streams.Stream_Element_Offset) is record
Value : Ada.Streams.Stream_Element_Array (0 .. Size);
end record;
Empty_Vector : Vector (-1);
end Array3;