Patchwork Fix PR ada/56474

login
register
mail settings
Submitter Eric Botcazou
Date May 7, 2013, 7:55 a.m.
Message ID <3701408.PcyJoRTMoB@polaris>
Download mbox | patch
Permalink /patch/242067/
State New
Headers show

Comments

Eric Botcazou - May 7, 2013, 7:55 a.m.
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  <ebotcazou@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  <ebotcazou@adacore.com>

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

Patch

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.  */