This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][RFC] Fix sizetype "sign" checks
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: ebotcazou at adacore dot com
- Date: Thu, 18 Aug 2011 13:37:22 +0200 (CEST)
- Subject: [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;