On Fri, 19 Aug 2011, Richard Guenther wrote:
> On Fri, 19 Aug 2011, Eric Botcazou wrote:
>
> > > 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 ;)
> >
> > Yes, the Ada compiler uses negative offsets for some peculiar constructs.
> > Nothing to do with the language per se, but with mechanisms implemented in
> > gigi to support some features of the language.
> >
> > > Eric, any better way of fixing this or would you be fine with this patch?
> >
> > Hard to say without seeing the complete patch and playing a little with it.
>
> This is the "complete" patch I am playing with currently, Ada bootstrap
> still fails for me unfortunately. Bootstrap for all other languages
> succeeds, but there are some regressions, mostly warning-related.
>
> Any help with pinpointing the Ada problem is welcome.
I have narrowed it down a bit. Building Ada + libada unpatched,
patching the tree and then running the gnat.dg testsuite reveals
FAIL: gnat.dg/align_max.adb execution test
FAIL: gnat.dg/array11.adb (test for warnings, line 12)
FAIL: gnat.dg/loop_optimization3.adb (test for excess errors)
WARNING: gnat.dg/loop_optimization3.adb compilation failed to produce
executable
FAIL: gnat.dg/object_overflow.adb (test for warnings, line 8)
FAIL: gnat.dg/thin_pointer2.adb execution test
FAIL: gnat.dg/unc_memfree.adb execution test
I just looked at gnat.dg/thin_pointer2.adb for now and we run into
utils2.c:build_simple_component_ref ()
/* If the field's offset has overflowed, do not attempt to access it
as doing so may trigger sanity checks deeper in the back-end.
Note that we don't need to warn since this will be done on trying
to declare the object. */
if (TREE_CODE (DECL_FIELD_OFFSET (field)) == INTEGER_CST
&& TREE_OVERFLOW (DECL_FIELD_OFFSET (field)))
return NULL_TREE;
for fields with "negative" offset:
(gdb) call debug_tree (field)
<field_decl 0x7ffff7ef7688 BOUNDS
type <record_type 0x7ffff7f0f150 string___XUB readonly DI
size <integer_cst 0x7ffff7ed3ec0 constant visited 64>
unit size <integer_cst 0x7ffff7ed3ee0 constant visited 8>
align 32 symtab 0 alias set -1 canonical type 0x7ffff7f0f150
fields <field_decl 0x7ffff7ef7558 LB0 type <integer_type
0x7ffff7ee35e8 integer>
visited nonaddressable SI file <built-in> line 0 col 0
size <integer_cst 0x7ffff7ee6200 constant visited 32>
unit size <integer_cst 0x7ffff7ee6220 constant visited 4>
align 32 offset_align 128
offset <integer_cst 0x7ffff7ed3f00 constant visited 0>
bit offset <integer_cst 0x7ffff7ed3f40 constant 0> context
<record_type 0x7ffff7f0f150 string___XUB> chain <field_decl 0x7ffff7ef75f0
UB0>> Ada size <integer_cst 0x7ffff7ed3ec0 64>
pointer_to_this <pointer_type 0x7ffff7f0f1f8> chain <type_decl
0x7ffff7ef48a0 string___XUB>>
readonly DI file <built-in> line 0 col 0 size <integer_cst
0x7ffff7ed3ec0 64> unit size <integer_cst 0x7ffff7ed3ee0 8>
align 32 offset_align 128
offset <integer_cst 0x7ffff7ee6e80 type <integer_type 0x7ffff7ee3000
sizetype> constant public overflow 18446744073709551608> bit offset
<integer_cst 0x7ffff7ed3f40 0> context <record_type 0x7ffff7f0fa80
string___XUT> chain <field_decl 0x7ffff7ef7720 ARRAY>>
which is computed by shift_unc_components_for_thin_pointers doing
DECL_FIELD_OFFSET (bounds_field)
= size_binop (MINUS_EXPR, size_zero_node, byte_position (array_field));
which (at least) after my change to always make size_binop report
overflow (even for unsigned sizetype, to match what the code was
doing previously for sign_extended_types) results in 0 - 8
overflowing.
The above is probably not always an INTEGER_CST(?), but the following
should "fix" this particular issue.
Index: trunk/gcc/ada/gcc-interface/utils.c
===================================================================
--- trunk.orig/gcc/ada/gcc-interface/utils.c 2011-08-24
16:06:21.000000000 +0200
+++ trunk/gcc/ada/gcc-interface/utils.c 2011-08-24 16:05:53.000000000
+0200
@@ -3413,6 +3413,12 @@ shift_unc_components_for_thin_pointers (
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;
Updated patch follows. I hope the above makes me go past
building libada with the patch (maybe even bootstrapping ...).
ACATS fails w/o the above are (x86_64-linux)
=== acats tests ===
FAIL: c36204d
FAIL: c41107a
FAIL: c43204a
FAIL: c43204c
FAIL: c43204e
FAIL: c43204f
FAIL: c43204g
FAIL: c43204h
FAIL: c43204i
FAIL: c43205i
FAIL: c52102a
FAIL: c52102b
FAIL: c52102c
FAIL: c52102d
FAIL: c95087a
FAIL: cc1311a
FAIL: cc3106b
FAIL: cc3224a
FAIL: cxh1001
Richard.
2011-06-16 Richard Guenther <[email protected]>
* fold-const.c (div_if_zero_remainder): sizetypes no longer
sign-extend.
* stor-layout.c (initialize_sizetypes): Likewise.
* 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.
* tree-cfg.c (verify_types_in_gimple_reference): Do not compare
sizes by pointer.
Index: trunk/gcc/fold-const.c
===================================================================
*** trunk.orig/gcc/fold-const.c 2011-08-24 15:34:13.000000000 +0200
--- trunk/gcc/fold-const.c 2011-08-24 15:36:22.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);
Index: trunk/gcc/stor-layout.c
===================================================================
*** trunk.orig/gcc/stor-layout.c 2011-08-24 15:34:13.000000000 +0200
--- trunk/gcc/stor-layout.c 2011-08-24 15:36:22.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-08-24 15:34:13.000000000 +0200
--- trunk/gcc/tree-ssa-ccp.c 2011-08-24 15:36:22.000000000 +0200
*************** bit_value_unop_1 (enum tree_code code, t
*** 1099,1112 ****
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;
--- 1099,1110 ----
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,
*** 1128,1135 ****
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;
--- 1126,1132 ----
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,
*** 1196,1208 ****
}
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);
--- 1193,1198 ----
*************** bit_value_binop_1 (enum tree_code code,
*** 1314,1325 ****
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
--- 1304,1310 ----
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-08-24 15:34:13.000000000 +0200
--- trunk/gcc/tree.c 2011-08-24 15:36:22.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-08-24 15:34:13.000000000
+0200
--- trunk/gcc/ada/gcc-interface/utils.c 2011-08-24 16:05:53.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-08-24 15:34:13.000000000 +0200
--- trunk/gcc/varasm.c 2011-08-24 15:36:23.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: trunk/gcc/c-family/c-common.c
===================================================================
*** trunk.orig/gcc/c-family/c-common.c 2011-08-24 15:34:13.000000000 +0200
--- trunk/gcc/c-family/c-common.c 2011-08-24 15:36:23.000000000 +0200
*************** pointer_int_sum (location_t loc, enum tr
*** 3790,3819 ****
intop = convert (int_type, TREE_OPERAND (intop, 0));
}
! /* Convert the integer argument to a type the same size as sizetype
so the multiply won't overflow spuriously. */
if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
! || TYPE_UNSIGNED (TREE_TYPE (intop)) != TYPE_UNSIGNED (sizetype))
intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype),
! TYPE_UNSIGNED (sizetype)), intop);
! /* Replace the integer argument with a suitable product by the object size.
! Do this multiplication as signed, then convert to the appropriate type
! for the pointer operation and disregard an overflow that occured only
! because of the sign-extension change in the latter conversion. */
! {
! tree t = build_binary_op (loc,
! MULT_EXPR, intop,
! convert (TREE_TYPE (intop), size_exp), 1);
! intop = convert (sizetype, t);
! if (TREE_OVERFLOW_P (intop) && !TREE_OVERFLOW (t))
! intop = build_int_cst_wide (TREE_TYPE (intop), TREE_INT_CST_LOW (intop),
! TREE_INT_CST_HIGH (intop));
! }
/* Create the sum or difference. */
if (resultcode == MINUS_EXPR)
! intop = fold_build1_loc (loc, NEGATE_EXPR, sizetype, intop);
ret = fold_build_pointer_plus_loc (loc, ptrop, intop);
--- 3790,3811 ----
intop = convert (int_type, TREE_OPERAND (intop, 0));
}
! /* Convert the integer argument to a signed type the same size as sizetype
so the multiply won't overflow spuriously. */
if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
! || TYPE_UNSIGNED (TREE_TYPE (intop)))
intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype),
! false), intop);
! /* Replace the integer argument with a suitable product by the
! object size. */
! intop = build_binary_op (loc,
! MULT_EXPR, intop,
! convert (TREE_TYPE (intop), size_exp), 1);
/* Create the sum or difference. */
if (resultcode == MINUS_EXPR)
! intop = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (intop), intop);
ret = fold_build_pointer_plus_loc (loc, ptrop, intop);