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.

Reply via email to