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;

Reply via email to