------- Comment #6 from rguenth at gcc dot gnu dot org 2007-09-21 10:20 ------- The problem is that fold_binary converts (long)ptr * -1 to (long)-ptr:
/* Transform x * -1 into -x. */ if (integer_all_onesp (arg1)) return fold_convert (type, negate_expr (arg0)); we shouldn't negate a pointer I think. Still if we negate op0 here, negate_expr strips sing-nops and ends up producing -ptr again :/ Sort of a mess... (asserting that we do not call negate_expr on pointers reveals even more problems) Anyway, the following fixes it: Index: fold-const.c =================================================================== --- fold-const.c (revision 128644) +++ fold-const.c (working copy) @@ -10242,7 +10242,7 @@ fold_binary (enum tree_code code, tree t return non_lvalue (fold_convert (type, arg0)); /* Transform x * -1 into -x. */ if (integer_all_onesp (arg1)) - return fold_convert (type, negate_expr (arg0)); + return fold_convert (type, negate_expr (op0)); /* Transform x * -C into -x * C if x is easily negatable. */ if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) == -1 Index: tree.h =================================================================== --- tree.h (revision 128644) +++ tree.h (working copy) @@ -1019,7 +1019,9 @@ extern void omp_clause_range_check_faile && (TYPE_MODE (TREE_TYPE (EXP)) \ == TYPE_MODE (TREE_TYPE (TREE_OPERAND (EXP, 0)))) \ && (TYPE_UNSIGNED (TREE_TYPE (EXP)) \ - == TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \ + == TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (EXP, 0)))) \ + && (POINTER_TYPE_P (TREE_TYPE (EXP)) \ + == POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \ (EXP) = TREE_OPERAND (EXP, 0) /* Like STRIP_NOPS, but don't alter the TREE_TYPE either. */ Andrew, with POINTER_PLUS_EXPR, do we still "allow" negating a pointer? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33146