> The first (C++) testcase is rejected since my SIZEOF_EXPR folding deferral
> changes, the problem is that
> -1 + (int) (sizeof (int) - 1)
> is first changed into
> -1 + (int) ((unsigned) sizeof (int) + UINT_MAX)
> and then fold_binary_loc reassociates it in int type into
> (int) sizeof (int) + [-2(overflow)], thus introducing overflow where
> there hasn't been originally.  maybe_const_value then refuses to fold it
> into constant due to that.  I've fixed that by the moving the TYPE_OVERFLOW
> check from before the operation to a check whether the whole reassociation
> doesn't introduce overflows (while previously it was testing solely
> for overflow introduced on fold_converted lit0/lit1 being combined
> together, not e.g. when overflow was introduced by fold_converting lit0
> resp. lit1, or for minus_lit{0,1} constants).

FWIW, no objections by me.

> Looking at that lead me to the second testcase below, which I hope is
> valid C, the overflow happens there in unsigned type, thus with defined
> wrapping, then there is implementation defined? conversion to signed type
> (but all our targets are two's complement), and associate_trees:
> was reassociating it in signed type, thus introducing signed overflow
> where there wasn't before.  Fixed by doing the reassociation in the unsigned
> type if (at least) one of the operands is of unsigned type.

I guess the natural question is then: if we start to change the type of the 
operation, why not always reassociate in the unsigned version of the type?

int
foo (int x, int y)
{
  return (x + 1) + (int) (y + 1);
}

int
bar (int x, unsigned int y)
{
  return (x + 1) + (int) (y + 1);
}

-- 
Eric Botcazou

Reply via email to