This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][Ada][C][C++] sizetypes no longer sign-extend


This patch makes us no longer treat unsigned sizetypes as sign-extending
which has caused trouble in the past (see the tree-ssa-ccp.c workarounds
removed below).

Most frontend specific changes below deal with the fact that overflow
behavior, as reported from size_binop, changes as unsigned sizetypes
now no longer overflow at SSIZETYPE_MAX but at USIZETYPE_MAX.  Diagnostics
expect warnings when overflow at half of the address-space occurs,
and Ada needs to pay special attention to its "negative" offsets,
all host_integerp (..., 1) checks have to be adjusted.

The patch bootstraps ok on x86_64-unknown-linux-gnu with all languages
enabled and tests with the following FAILs with {,-m32}:

Running target unix//-m32
FAIL: g++.dg/tree-ssa/pr19807.C scan-tree-dump-times optimized "\\+ 
0x0f*;" 1

still need to figure out how to properly quote that regexp for TCL
scanning for the various (sizetype)-1U printings ...

Running target unix/{,-m32}
FAIL: gcc.dg/pr42611.c  (test for errors, line 17)
FAIL: gcc.dg/pr42611.c (test for excess errors)

another missed overflow check, looking at it now

Running target unix/
FAIL: gnat.dg/array11.adb  (test for warnings, line 12)
FAIL: gnat.dg/object_overflow.adb  (test for warnings, line 8)

Running target unix//-m32
FAIL: gnat.dg/array11.adb  (test for warnings, line 12)
FAIL: gnat.dg/frame_overflow.adb  (test for errors, line 17)
FAIL: gnat.dg/frame_overflow.adb  (test for errors, line 24)
FAIL: gnat.dg/object_overflow.adb  (test for warnings, line 8)

probably similar, I pushed back Ada diagnostic tests for now,
but will look at them after resolving the above remaining FAIL.

Thus, I think the patch is ready to get review, adjustments, esp.
for the Ada pieces are welcome.

Thanks,
Richard.

2011-09-02  Richard Guenther  <rguenther@suse.de>

	* fold-const.c (div_if_zero_remainder): sizetypes no longer
	sign-extend.
	(int_const_binop_1): New worker for int_const_binop with
	overflowable parameter.  Pass it through
	to force_fit_type_double.
	(int_const_binop): Wrap around int_const_binop_1 with overflowable
	equal to one.
	(size_binop_loc): Call int_const_binop_1 with overflowable equal
	to minus one, forcing overflow detection for even unsigned types.
	(fold_binary_loc): Call try_move_mult_to_index with signed offset.
	* stor-layout.c (initialize_sizetypes): sizetypes no longer
	sign-extend.
	* tree-ssa-ccp.c (bit_value_unop_1): Likewise.
	(bit_value_binop_1): Likewise.
	* tree.c (double_int_to_tree): Likewise.
	(double_int_fits_to_tree_p): Likewise.
	(force_fit_type_double): Likewise.
	(host_integerp): Likewise.
	(int_fits_type_p): Likewise.
	* varasm.c (assemble_variable): Adjust check for too large
	variables by making sure the MSB of the size is not set.
	(output_constructor_regular_field): Sign-extend the field-offset
	to cater for negative offsets produced by the Ada frontend.
	* omp-low.c (extract_omp_for_data): Convert the loop step to
	signed for pointer adjustments.

	c/
	* c-decl.c (grokdeclarator): Properly check for sizes that
	cover more than half of the address-space.

	cp/
	* decl.c (grokdeclarator): Properly check for sizes that
	cover more than half of the address-space.

	ada/
	* gcc-interface/utils.c (rest_of_record_type_compilation): Check
	for positive offsets with MSB not set.
	(shift_unc_components_for_thin_pointers): Drop overflow bit
	on negative offsets.

	* g++.dg/tree-ssa/pr19807.C: Adjust.

Index: trunk/gcc/fold-const.c
===================================================================
*** trunk.orig/gcc/fold-const.c	2011-09-01 09:12:28.000000000 +0200
--- trunk/gcc/fold-const.c	2011-09-02 14:01:05.000000000 +0200
*************** div_if_zero_remainder (enum tree_code co
*** 194,202 ****
       does the correct thing for POINTER_PLUS_EXPR where we want
       a signed division.  */
    uns = TYPE_UNSIGNED (TREE_TYPE (arg2));
-   if (TREE_CODE (TREE_TYPE (arg2)) == INTEGER_TYPE
-       && TYPE_IS_SIZETYPE (TREE_TYPE (arg2)))
-     uns = false;
  
    quo = double_int_divmod (tree_to_double_int (arg1),
  			   tree_to_double_int (arg2),
--- 194,199 ----
*************** int_binop_types_match_p (enum tree_code
*** 938,945 ****
     to produce a new constant.  Return NULL_TREE if we don't know how
     to evaluate CODE at compile-time.  */
  
! tree
! int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2)
  {
    double_int op1, op2, res, tmp;
    tree t;
--- 935,943 ----
     to produce a new constant.  Return NULL_TREE if we don't know how
     to evaluate CODE at compile-time.  */
  
! static tree
! int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree arg2,
! 		   int overflowable)
  {
    double_int op1, op2, res, tmp;
    tree t;
*************** int_const_binop (enum tree_code code, co
*** 1081,1093 ****
        return NULL_TREE;
      }
  
!   t = force_fit_type_double (TREE_TYPE (arg1), res, 1,
  			     ((!uns || is_sizetype) && overflow)
  			     | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
  
    return t;
  }
  
  /* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
     constant.  We assume ARG1 and ARG2 have the same data type, or at least
     are the same kind of constant and the same machine mode.  Return zero if
--- 1079,1097 ----
        return NULL_TREE;
      }
  
!   t = force_fit_type_double (TREE_TYPE (arg1), res, overflowable,
  			     ((!uns || is_sizetype) && overflow)
  			     | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
  
    return t;
  }
  
+ tree
+ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2)
+ {
+   return int_const_binop_1 (code, arg1, arg2, 1);
+ }
+ 
  /* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
     constant.  We assume ARG1 and ARG2 have the same data type, or at least
     are the same kind of constant and the same machine mode.  Return zero if
*************** size_binop_loc (location_t loc, enum tre
*** 1448,1455 ****
  	    return arg1;
  	}
  
!       /* Handle general case of two integer constants.  */
!       return int_const_binop (code, arg0, arg1);
      }
  
    return fold_build2_loc (loc, code, type, arg0, arg1);
--- 1452,1461 ----
  	    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 fold_build2_loc (loc, code, type, arg0, arg1);
*************** fold_binary_loc (location_t loc,
*** 9599,9605 ****
        if (TREE_CODE (arg0) == ADDR_EXPR)
  	{
  	  tem = try_move_mult_to_index (loc, arg0,
! 					fold_convert_loc (loc, sizetype, arg1));
  	  if (tem)
  	    return fold_convert_loc (loc, type, tem);
  	}
--- 9605,9612 ----
        if (TREE_CODE (arg0) == ADDR_EXPR)
  	{
  	  tem = try_move_mult_to_index (loc, arg0,
! 					fold_convert_loc (loc,
! 							  ssizetype, arg1));
  	  if (tem)
  	    return fold_convert_loc (loc, type, tem);
  	}
Index: trunk/gcc/stor-layout.c
===================================================================
*** trunk.orig/gcc/stor-layout.c	2011-09-01 09:12:28.000000000 +0200
--- trunk/gcc/stor-layout.c	2011-09-02 14:01:05.000000000 +0200
*************** initialize_sizetypes (void)
*** 2235,2245 ****
    TYPE_SIZE_UNIT (sizetype) = size_int (GET_MODE_SIZE (TYPE_MODE (sizetype)));
    set_min_and_max_values_for_integral_type (sizetype, precision,
  					    /*is_unsigned=*/true);
-   /* sizetype is unsigned but we need to fix TYPE_MAX_VALUE so that it is
-      sign-extended in a way consistent with force_fit_type.  */
-   TYPE_MAX_VALUE (sizetype)
-     = double_int_to_tree (sizetype,
- 			  tree_to_double_int (TYPE_MAX_VALUE (sizetype)));
  
    SET_TYPE_MODE (bitsizetype, smallest_mode_for_size (bprecision, MODE_INT));
    TYPE_ALIGN (bitsizetype) = GET_MODE_ALIGNMENT (TYPE_MODE (bitsizetype));
--- 2235,2240 ----
*************** initialize_sizetypes (void)
*** 2248,2258 ****
      = size_int (GET_MODE_SIZE (TYPE_MODE (bitsizetype)));
    set_min_and_max_values_for_integral_type (bitsizetype, bprecision,
  					    /*is_unsigned=*/true);
-   /* bitsizetype is unsigned but we need to fix TYPE_MAX_VALUE so that it is
-      sign-extended in a way consistent with force_fit_type.  */
-   TYPE_MAX_VALUE (bitsizetype)
-     = double_int_to_tree (bitsizetype,
- 			  tree_to_double_int (TYPE_MAX_VALUE (bitsizetype)));
  
    /* Create the signed variants of *sizetype.  */
    ssizetype = make_signed_type (TYPE_PRECISION (sizetype));
--- 2243,2248 ----
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c	2011-09-02 13:56:19.000000000 +0200
--- trunk/gcc/tree-ssa-ccp.c	2011-09-02 14:01:05.000000000 +0200
*************** bit_value_unop_1 (enum tree_code code, t
*** 1100,1113 ****
  	bool uns;
  
  	/* First extend mask and value according to the original type.  */
! 	uns = (TREE_CODE (rtype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (rtype)
! 	       ? 0 : TYPE_UNSIGNED (rtype));
  	*mask = double_int_ext (rmask, TYPE_PRECISION (rtype), uns);
  	*val = double_int_ext (rval, TYPE_PRECISION (rtype), uns);
  
  	/* Then extend mask and value according to the target type.  */
! 	uns = (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
! 	       ? 0 : TYPE_UNSIGNED (type));
  	*mask = double_int_ext (*mask, TYPE_PRECISION (type), uns);
  	*val = double_int_ext (*val, TYPE_PRECISION (type), uns);
  	break;
--- 1100,1111 ----
  	bool uns;
  
  	/* First extend mask and value according to the original type.  */
! 	uns = TYPE_UNSIGNED (rtype);
  	*mask = double_int_ext (rmask, TYPE_PRECISION (rtype), uns);
  	*val = double_int_ext (rval, TYPE_PRECISION (rtype), uns);
  
  	/* Then extend mask and value according to the target type.  */
! 	uns = TYPE_UNSIGNED (type);
  	*mask = double_int_ext (*mask, TYPE_PRECISION (type), uns);
  	*val = double_int_ext (*val, TYPE_PRECISION (type), uns);
  	break;
*************** bit_value_binop_1 (enum tree_code code,
*** 1129,1136 ****
  		   tree r1type, double_int r1val, double_int r1mask,
  		   tree r2type, double_int r2val, double_int r2mask)
  {
!   bool uns = (TREE_CODE (type) == INTEGER_TYPE
! 	      && TYPE_IS_SIZETYPE (type) ? 0 : TYPE_UNSIGNED (type));
    /* Assume we'll get a constant result.  Use an initial varying value,
       we fall back to varying in the end if necessary.  */
    *mask = double_int_minus_one;
--- 1127,1133 ----
  		   tree r1type, double_int r1val, double_int r1mask,
  		   tree r2type, double_int r2val, double_int r2mask)
  {
!   bool uns = TYPE_UNSIGNED (type);
    /* Assume we'll get a constant result.  Use an initial varying value,
       we fall back to varying in the end if necessary.  */
    *mask = double_int_minus_one;
*************** bit_value_binop_1 (enum tree_code code,
*** 1197,1209 ****
  	    }
  	  else if (shift < 0)
  	    {
- 	      /* ???  We can have sizetype related inconsistencies in
- 		 the IL.  */
- 	      if ((TREE_CODE (r1type) == INTEGER_TYPE
- 		   && (TYPE_IS_SIZETYPE (r1type)
- 		       ? 0 : TYPE_UNSIGNED (r1type))) != uns)
- 		break;
- 
  	      shift = -shift;
  	      *mask = double_int_rshift (r1mask, shift,
  					 TYPE_PRECISION (type), !uns);
--- 1194,1199 ----
*************** bit_value_binop_1 (enum tree_code code,
*** 1315,1326 ****
  	  break;
  
  	/* For comparisons the signedness is in the comparison operands.  */
! 	uns = (TREE_CODE (r1type) == INTEGER_TYPE
! 	       && TYPE_IS_SIZETYPE (r1type) ? 0 : TYPE_UNSIGNED (r1type));
! 	/* ???  We can have sizetype related inconsistencies in the IL.  */
! 	if ((TREE_CODE (r2type) == INTEGER_TYPE
! 	     && TYPE_IS_SIZETYPE (r2type) ? 0 : TYPE_UNSIGNED (r2type)) != uns)
! 	  break;
  
  	/* If we know the most significant bits we know the values
  	   value ranges by means of treating varying bits as zero
--- 1305,1311 ----
  	  break;
  
  	/* For comparisons the signedness is in the comparison operands.  */
! 	uns = TYPE_UNSIGNED (r1type);
  
  	/* If we know the most significant bits we know the values
  	   value ranges by means of treating varying bits as zero
Index: trunk/gcc/tree.c
===================================================================
*** trunk.orig/gcc/tree.c	2011-09-01 09:12:28.000000000 +0200
--- trunk/gcc/tree.c	2011-09-02 14:01:05.000000000 +0200
*************** tree
*** 1059,1067 ****
  double_int_to_tree (tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = (!TYPE_UNSIGNED (type)
! 			     || (TREE_CODE (type) == INTEGER_TYPE
! 				 && TYPE_IS_SIZETYPE (type)));
  
    cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
  
--- 1059,1065 ----
  double_int_to_tree (tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = !TYPE_UNSIGNED (type);
  
    cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
  
*************** bool
*** 1075,1083 ****
  double_int_fits_to_tree_p (const_tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = (!TYPE_UNSIGNED (type)
! 			     || (TREE_CODE (type) == INTEGER_TYPE
! 				 && TYPE_IS_SIZETYPE (type)));
  
    double_int ext
      = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
--- 1073,1079 ----
  double_int_fits_to_tree_p (const_tree type, double_int cst)
  {
    /* Size types *are* sign extended.  */
!   bool sign_extended_type = !TYPE_UNSIGNED (type);
  
    double_int ext
      = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
*************** force_fit_type_double (tree type, double
*** 1107,1115 ****
    bool sign_extended_type;
  
    /* Size types *are* sign extended.  */
!   sign_extended_type = (!TYPE_UNSIGNED (type)
!                         || (TREE_CODE (type) == INTEGER_TYPE
!                             && TYPE_IS_SIZETYPE (type)));
  
    /* If we need to set overflow flags, return a new unshared node.  */
    if (overflowed || !double_int_fits_to_tree_p(type, cst))
--- 1103,1109 ----
    bool sign_extended_type;
  
    /* Size types *are* sign extended.  */
!   sign_extended_type = !TYPE_UNSIGNED (type);
  
    /* If we need to set overflow flags, return a new unshared node.  */
    if (overflowed || !double_int_fits_to_tree_p(type, cst))
*************** host_integerp (const_tree t, int pos)
*** 6496,6504 ****
  	       && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
  	      || (! pos && TREE_INT_CST_HIGH (t) == -1
  		  && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0
! 		  && (!TYPE_UNSIGNED (TREE_TYPE (t))
! 		      || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
! 			  && TYPE_IS_SIZETYPE (TREE_TYPE (t)))))
  	      || (pos && TREE_INT_CST_HIGH (t) == 0)));
  }
  
--- 6490,6496 ----
  	       && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
  	      || (! pos && TREE_INT_CST_HIGH (t) == -1
  		  && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0
! 		  && !TYPE_UNSIGNED (TREE_TYPE (t)))
  	      || (pos && TREE_INT_CST_HIGH (t) == 0)));
  }
  
*************** int_fits_type_p (const_tree c, const_tre
*** 8190,8207 ****
    dc = tree_to_double_int (c);
    unsc = TYPE_UNSIGNED (TREE_TYPE (c));
  
-   if (TREE_CODE (TREE_TYPE (c)) == INTEGER_TYPE
-       && TYPE_IS_SIZETYPE (TREE_TYPE (c))
-       && unsc)
-     /* So c is an unsigned integer whose type is sizetype and type is not.
-        sizetype'd integers are sign extended even though they are
-        unsigned. If the integer value fits in the lower end word of c,
-        and if the higher end word has all its bits set to 1, that
-        means the higher end bits are set to 1 only for sign extension.
-        So let's convert c into an equivalent zero extended unsigned
-        integer.  */
-     dc = double_int_zext (dc, TYPE_PRECISION (TREE_TYPE (c)));
- 
  retry:
    type_low_bound = TYPE_MIN_VALUE (type);
    type_high_bound = TYPE_MAX_VALUE (type);
--- 8182,8187 ----
*************** retry:
*** 8220,8229 ****
    if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
      {
        dd = tree_to_double_int (type_low_bound);
-       if (TREE_CODE (type) == INTEGER_TYPE
- 	  && TYPE_IS_SIZETYPE (type)
- 	  && TYPE_UNSIGNED (type))
- 	dd = double_int_zext (dd, TYPE_PRECISION (type));
        if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_low_bound)))
  	{
  	  int c_neg = (!unsc && double_int_negative_p (dc));
--- 8200,8205 ----
*************** retry:
*** 8245,8254 ****
    if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
      {
        dd = tree_to_double_int (type_high_bound);
-       if (TREE_CODE (type) == INTEGER_TYPE
- 	  && TYPE_IS_SIZETYPE (type)
- 	  && TYPE_UNSIGNED (type))
- 	dd = double_int_zext (dd, TYPE_PRECISION (type));
        if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_high_bound)))
  	{
  	  int c_neg = (!unsc && double_int_negative_p (dc));
--- 8221,8226 ----
Index: trunk/gcc/ada/gcc-interface/utils.c
===================================================================
*** trunk.orig/gcc/ada/gcc-interface/utils.c	2011-09-01 09:12:28.000000000 +0200
--- trunk/gcc/ada/gcc-interface/utils.c	2011-09-02 14:01:05.000000000 +0200
*************** rest_of_record_type_compilation (tree re
*** 948,954 ****
  	    pos = compute_related_constant (curpos, last_pos);
  
  	  if (!pos && TREE_CODE (curpos) == MULT_EXPR
! 	      && host_integerp (TREE_OPERAND (curpos, 1), 1))
  	    {
  	      tree offset = TREE_OPERAND (curpos, 0);
  	      align = tree_low_cst (TREE_OPERAND (curpos, 1), 1);
--- 948,955 ----
  	    pos = compute_related_constant (curpos, last_pos);
  
  	  if (!pos && TREE_CODE (curpos) == MULT_EXPR
! 	      && host_integerp (TREE_OPERAND (curpos, 1), 1)
! 	      && !tree_int_cst_sign_bit (TREE_OPERAND (curpos, 1)))
  	    {
  	      tree offset = TREE_OPERAND (curpos, 0);
  	      align = tree_low_cst (TREE_OPERAND (curpos, 1), 1);
*************** rest_of_record_type_compilation (tree re
*** 960,966 ****
  	      offset = remove_conversions (offset, true);
  	      if (TREE_CODE (offset) == BIT_AND_EXPR
  		  && host_integerp (TREE_OPERAND (offset, 1), 0)
! 		  && TREE_INT_CST_HIGH (TREE_OPERAND (offset, 1)) < 0)
  		{
  		  unsigned int pow
  		    = - tree_low_cst (TREE_OPERAND (offset, 1), 0);
--- 961,967 ----
  	      offset = remove_conversions (offset, true);
  	      if (TREE_CODE (offset) == BIT_AND_EXPR
  		  && host_integerp (TREE_OPERAND (offset, 1), 0)
! 		  && tree_int_cst_sign_bit (TREE_OPERAND (offset, 1)))
  		{
  		  unsigned int pow
  		    = - tree_low_cst (TREE_OPERAND (offset, 1), 0);
*************** rest_of_record_type_compilation (tree re
*** 975,982 ****
  		   && TREE_CODE (TREE_OPERAND (curpos, 1)) == INTEGER_CST
  		   && TREE_CODE (TREE_OPERAND (curpos, 0)) == MULT_EXPR
  		   && host_integerp (TREE_OPERAND
! 				     (TREE_OPERAND (curpos, 0), 1),
! 				     1))
  	    {
  	      align
  		= tree_low_cst
--- 976,984 ----
  		   && TREE_CODE (TREE_OPERAND (curpos, 1)) == INTEGER_CST
  		   && TREE_CODE (TREE_OPERAND (curpos, 0)) == MULT_EXPR
  		   && host_integerp (TREE_OPERAND
! 				     (TREE_OPERAND (curpos, 0), 1), 1)
! 		   && !tree_int_cst_sign_bit (TREE_OPERAND
! 					      (TREE_OPERAND (curpos, 0), 1)))
  	    {
  	      align
  		= tree_low_cst
*************** shift_unc_components_for_thin_pointers (
*** 3411,3416 ****
--- 3413,3424 ----
  
    DECL_FIELD_OFFSET (bounds_field)
      = size_binop (MINUS_EXPR, size_zero_node, byte_position (array_field));
+   if (TREE_CODE (DECL_FIELD_OFFSET (bounds_field)) == INTEGER_CST
+       && TREE_OVERFLOW (DECL_FIELD_OFFSET (bounds_field)))
+     DECL_FIELD_OFFSET (bounds_field)
+       = build_int_cst_wide (sizetype,
+ 			    TREE_INT_CST_LOW (DECL_FIELD_OFFSET (bounds_field)),
+ 			    TREE_INT_CST_HIGH (DECL_FIELD_OFFSET (bounds_field)));
  
    DECL_FIELD_OFFSET (array_field) = size_zero_node;
    DECL_FIELD_BIT_OFFSET (array_field) = bitsize_zero_node;
Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c	2011-09-01 09:12:28.000000000 +0200
--- trunk/gcc/varasm.c	2011-09-02 14:01:05.000000000 +0200
*************** assemble_variable (tree decl, int top_le
*** 1980,1986 ****
      return;
  
    if (! dont_output_data
!       && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
      {
        error ("size of variable %q+D is too large", decl);
        return;
--- 1980,1989 ----
      return;
  
    if (! dont_output_data
!       && (! host_integerp (DECL_SIZE_UNIT (decl), 1)
! 	  /* Restrict sizes of variables to half the address-space by
! 	     making sure the msb of the size is not set.  */
! 	  || tree_int_cst_sign_bit (DECL_SIZE_UNIT (decl)) != 0))
      {
        error ("size of variable %q+D is too large", decl);
        return;
*************** output_constructor_regular_field (oc_loc
*** 4746,4753 ****
  
    if (local->index != NULL_TREE)
      {
!       double_int idx = double_int_sub (tree_to_double_int (local->index),
! 				       tree_to_double_int (local->min_index));
        gcc_assert (double_int_fits_in_shwi_p (idx));
        fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
  		  * idx.low);
--- 4749,4763 ----
  
    if (local->index != NULL_TREE)
      {
!       /* ???  Ada has negative DECL_FIELD_OFFSETs but we are using an
!          unsigned sizetype so make sure to sign-extend the indices before
! 	 subtracting them.  */
!       unsigned prec = TYPE_PRECISION (sizetype);
!       double_int idx
! 	= double_int_sub (double_int_sext (tree_to_double_int (local->index),
! 					   prec),
! 			  double_int_sext (tree_to_double_int
! 					     (local->min_index), prec));
        gcc_assert (double_int_fits_in_shwi_p (idx));
        fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
  		  * idx.low);
Index: trunk/gcc/omp-low.c
===================================================================
*** trunk.orig/gcc/omp-low.c	2011-09-01 09:12:28.000000000 +0200
--- trunk/gcc/omp-low.c	2011-09-02 14:01:05.000000000 +0200
*************** extract_omp_for_data (gimple for_stmt, s
*** 335,343 ****
        switch (TREE_CODE (t))
  	{
  	case PLUS_EXPR:
- 	case POINTER_PLUS_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  break;
  	case MINUS_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  loop->step = fold_build1_loc (loc,
--- 335,345 ----
        switch (TREE_CODE (t))
  	{
  	case PLUS_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  break;
+ 	case POINTER_PLUS_EXPR:
+ 	  loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
+ 	  break;
  	case MINUS_EXPR:
  	  loop->step = TREE_OPERAND (t, 1);
  	  loop->step = fold_build1_loc (loc,
Index: trunk/gcc/c-decl.c
===================================================================
*** trunk.orig/gcc/c-decl.c	2011-09-01 09:12:28.000000000 +0200
--- trunk/gcc/c-decl.c	2011-09-02 14:01:05.000000000 +0200
*************** grokdeclarator (const struct c_declarato
*** 5708,5719 ****
    if (bitfield)
      check_bitfield_type_and_width (&type, width, name);
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
      {
        if (name)
  	error_at (loc, "size of array %qE is too large", name);
--- 5708,5720 ----
    if (bitfield)
      check_bitfield_type_and_width (&type, width, name);
  
!   /* Did array size calculations overflow or does the array cover more
!      than half of the address-space?  */
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && (TREE_OVERFLOW (TYPE_SIZE_UNIT (type))
! 	  || tree_int_cst_sign_bit (TYPE_SIZE_UNIT (type)) != 0))
      {
        if (name)
  	error_at (loc, "size of array %qE is too large", name);
Index: trunk/gcc/cp/decl.c
===================================================================
*** trunk.orig/gcc/cp/decl.c	2011-09-01 09:12:28.000000000 +0200
--- trunk/gcc/cp/decl.c	2011-09-02 14:01:05.000000000 +0200
*************** grokdeclarator (const cp_declarator *dec
*** 9505,9516 ****
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* Did array size calculations overflow?  */
! 
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
      {
        error ("size of array %qs is too large", name);
        /* If we proceed with the array type as it is, we'll eventually
--- 9505,9517 ----
          error ("non-parameter %qs cannot be a parameter pack", name);
      }
  
!   /* Did array size calculations overflow or does the array cover more
!      than half of the address-space?  */
    if (TREE_CODE (type) == ARRAY_TYPE
        && COMPLETE_TYPE_P (type)
        && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
!       && (TREE_OVERFLOW (TYPE_SIZE_UNIT (type))
! 	  || tree_int_cst_sign_bit (TYPE_SIZE_UNIT (type)) != 0))
      {
        error ("size of array %qs is too large", name);
        /* If we proceed with the array type as it is, we'll eventually
Index: trunk/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
===================================================================
*** trunk.orig/gcc/testsuite/g++.dg/tree-ssa/pr19807.C	2011-09-01 09:12:28.000000000 +0200
--- trunk/gcc/testsuite/g++.dg/tree-ssa/pr19807.C	2011-09-02 14:31:14.000000000 +0200
*************** void bar(int i)
*** 25,30 ****
     Simply test for the existence of +1 and -1 once, which also ensures
     the above.  If the addition/subtraction would be applied to the
     pointer we would instead see +-4 (or 8, depending on sizeof(int)).  */
! /* { dg-final { scan-tree-dump-times "\\\+ -1;" 1 "optimized" } } */
  /* { dg-final { scan-tree-dump-times "\\\+ 1;" 1 "optimized" } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */
--- 25,30 ----
     Simply test for the existence of +1 and -1 once, which also ensures
     the above.  If the addition/subtraction would be applied to the
     pointer we would instead see +-4 (or 8, depending on sizeof(int)).  */
! /* { dg-final { scan-tree-dump-times "\\\+ \\\\(18446744073709551615\\\\|4294967295\\\\);" 1 "optimized" } } */
  /* { dg-final { scan-tree-dump-times "\\\+ 1;" 1 "optimized" } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]