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  <rguent...@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;

Reply via email to