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.

As suggested by Richard, we can use int_const_binop in lieu of size_binop when 
we don't want overflow detection for sizetype in gigi.

Bootstrapped/regtested on x86_64-suse-linux, applied on mainline and branch.


2013-05-07  Eric Botcazou  <ebotca...@adacore.com>

        PR ada/56474
        * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Use
        int_const_binop to shift bounds by 1 when they are integer constants.


2013-05-07  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/specs/array3.ads: New test.


-- 
Eric Botcazou
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 198517)
+++ gcc-interface/decl.c	(working copy)
@@ -2447,15 +2447,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 							gnu_orig_max,
 							gnu_orig_min),
 				       gnu_min,
-				       size_binop (PLUS_EXPR, gnu_max,
-						   size_one_node));
+				       int_const_binop (PLUS_EXPR, gnu_max,
+							size_one_node));
 		}
 
 	      /* Finally we use (hb >= lb) ? hb : lb - 1 for the upper bound
 		 in all the other cases.  Note that, here as well as above,
 		 the condition used in the comparison must be equivalent to
 		 the condition (length != 0).  This is relied upon in order
-		 to optimize array comparisons in compare_arrays.  */
+		 to optimize array comparisons in compare_arrays.  Moreover
+		 we use int_const_binop for the shift by 1 if the bound is
+		 constant to avoid any unwanted overflow.  */
 	      else
 		gnu_high
 		  = build_cond_expr (sizetype,
@@ -2464,8 +2466,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 						      gnu_orig_max,
 						      gnu_orig_min),
 				     gnu_max,
-				     size_binop (MINUS_EXPR, gnu_min,
-						 size_one_node));
+				     TREE_CODE (gnu_min) == INTEGER_CST
+				     ? int_const_binop (MINUS_EXPR, gnu_min,
+							size_one_node)
+				     : size_binop (MINUS_EXPR, gnu_min,
+						   size_one_node));
 
 	      /* Reuse the index type for the range type.  Then make an index
 		 type with the size range in sizetype.  */
-- 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