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][RFC] Fix sizetype "sign" checks


The following fixes a few places that think that using
host_integerp (t, 1) with t being a sizetype constant to
verify the value is "positive" is a good idea.  sizetype
is an unsigned type (yes, still sign-extended), so
testing for a positive value is at least weird.

The patch below adds tree_int_cst_sign_bit tests in
addition to the existing host_integerp checks.  The
varasm.c hunk removes a few diagnostic regressions
when you make sizetypes no longer sign-extended,
the second solves Ada bootstrap problems in that case.

Looking at the Ada case I believe this happens because
Ada has negative DECL_FIELD_OFFSET values (but that's
again in sizetype, not ssizetype)?  Other host_integerp
uses in Ada operate on sizes where I hope those are
never negative ;)

Eric, any better way of fixing this or would you be fine
with this patch?

Thanks,
Richard.

2011-08-18  Richard Guenther  <rguenther@suse.de>

	* varasm.c (assemble_variable): Fix declaration size check.

	ada/
	* gcc-interface/utils.c (rest_of_record_type_compilation):
	Fix sizetype "sign" checks.


Index: trunk/gcc/ada/gcc-interface/utils.c
===================================================================
*** trunk.orig/gcc/ada/gcc-interface/utils.c	2011-08-18 12:58:17.000000000 +0200
--- trunk/gcc/ada/gcc-interface/utils.c	2011-08-18 13:18:39.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), 1))
  	    {
  	      align
  		= tree_low_cst
Index: trunk/gcc/varasm.c
===================================================================
*** trunk.orig/gcc/varasm.c	2011-08-18 12:58:17.000000000 +0200
--- trunk/gcc/varasm.c	2011-08-18 13:18:17.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;


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