On Wed, Oct 1, 2008 at 12:20 AM, DJ Delorie <[EMAIL PROTECTED]> wrote: > > I've got a partial patch which works with older (4.3) gccs, but fails > gimple's check for trunk (attached). My trivial test case... > > char * > foo (char *a, int b) > { > return a-b; > } > > ...fails thusly: > > <integer_type 0xb7f52c30 public unsigned SI > size <integer_cst 0xb7ee7540 type <integer_type 0xb7ef5068 bit_size_type> > constant 32> > unit size <integer_cst 0xb7ee72bc type <integer_type 0xb7ef5000 unsigned > int> constant 4> > align 8 symtab 0 alias set -1 canonical type 0xb7f52c30 precision 32 min > <integer_cst 0xb7f6a0c4 0> max <integer_cst 0xb7ee7e8c 4294967295>> > <integer_type 0xb7ef5000 unsigned int public unsigned sizetype HI > size <integer_cst 0xb7ee7428 type <integer_type 0xb7ef5068 bit_size_type> > constant 16> > unit size <integer_cst 0xb7ee7444 type <integer_type 0xb7ef5000 unsigned > int> constant 2> > align 8 symtab 0 alias set -1 canonical type 0xb7efc000 precision 16 min > <integer_cst 0xb7ee74d0 0> max <integer_cst 0xb7ee7ad4 -1>> > useless false: ../../gcc/gcc/tree-ssa.c 1092 > dj.c: In function 'foo': > dj.c:2: error: type mismatch in pointer plus expression > D.1194 = a + D.1196; > > char * > > char * > > <unnamed-unsigned:32> > > D.1194 = a + D.1196; > > dj.c:2: internal compiler error: verify_gimple failed > > > I'm obviously doing something wrong in the cast-to-bigger step. How > can I get this to pass gimple? What I'm trying to accomplish is this: > > 1. Values added to pointers need to be treated as signed (at least, if > they're signed types, certainly if you're going to use a > NEGATE_EXPR). > > 2. If sizeof(size_t) < sizeof(void *), sign extend the intop to be > pointer-sized before adding it. > > > > Index: c-common.c > =================================================================== > --- c-common.c (revision 140759) > +++ c-common.c (working copy) > @@ -3337,20 +3337,28 @@ pointer_int_sum (enum tree_code resultco > 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. */ > - intop = convert (sizetype, > + intop = convert (ssizetype, > build_binary_op (EXPR_LOCATION (intop), > MULT_EXPR, intop, > convert (TREE_TYPE (intop), size_exp), 1)); > > /* Create the sum or difference. */ > if (resultcode == MINUS_EXPR) > - intop = fold_build1 (NEGATE_EXPR, sizetype, intop); > + intop = fold_build1 (NEGATE_EXPR, ssizetype, intop); > + > + if (TREE_CODE (result_type) == POINTER_TYPE > + && TYPE_PRECISION (result_type) > TYPE_PRECISION (TREE_TYPE (intop))) > + { > + tree iptr_type = c_common_type_for_mode (TYPE_MODE (result_type), > + TYPE_UNSIGNED (result_type)); > + intop = fold_build1 (NOP_EXPR, iptr_type, intop); > + } > > ret = fold_build2 (POINTER_PLUS_EXPR, result_type, ptrop, intop); > > fold_undefer_and_ignore_overflow_warnings (); > > return ret;
I think this is the wrong place to fix this. If you would override the sizetypes precision from your target, would that fix it? That is, in stor-layout.c set_sizetype make the target allow adjusting the passed type (which is supposed to be sizetype). If at all then these types should be consistent. Richard.