> 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