------- Comment #11 from rguenth at gcc dot gnu dot org 2010-07-28 09:32
-------
I suppose that
uy = -ux;
is really
uy = (unsigned char) -(int) ux;
as unsigned char promotes to int. We then incorrectly
narrow this to -(signed char) ux.
We do this again in convert_to_integer. Our bag of premature (and bogus)
optimizations.
case NEGATE_EXPR:
case BIT_NOT_EXPR:
/* This is not correct for ABS_EXPR,
since we must test the sign before truncation. */
{
tree typex;
/* Don't do unsigned arithmetic where signed was wanted,
or vice versa. */
if (TYPE_UNSIGNED (TREE_TYPE (expr)))
typex = unsigned_type_for (type);
else
typex = signed_type_for (type);
return convert (type,
fold_build1 (ex_form, typex,
convert (typex,
TREE_OPERAND (expr, 0))));
well - I have no idea why we can't always choose an unsigned type here
(testing that now).
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45034