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;