This fixes PR52549 - we are running into an overzealous assert that wants to make sure we don't have PLUS_EXPR on pointers. But that code does not really check this and falls foul of the conversion removal code right before it that transforms (void *)(a + b) to a + b.
Fixed as follows. Bootstrap and regtest pending on x86_64-unknown-linux-gnu. Ok? Thanks, Richard. 2012-04-12 Richard Guenther <rguent...@suse.de> PR c/52549 * c-typeck.c (pointer_diff): Remove bogus assert. * gcc.dg/pr52549.c: New testcase. Index: gcc/c-typeck.c =================================================================== --- gcc/c-typeck.c (revision 186373) +++ gcc/c-typeck.c (working copy) @@ -3446,8 +3446,6 @@ pointer_diff (location_t loc, tree op0, else con1 = op1; - gcc_assert (TREE_CODE (con0) != PLUS_EXPR - && TREE_CODE (con1) != PLUS_EXPR); if (TREE_CODE (con0) == POINTER_PLUS_EXPR) { lit0 = TREE_OPERAND (con0, 1); Index: gcc/testsuite/gcc.dg/pr52549.c =================================================================== --- gcc/testsuite/gcc.dg/pr52549.c (revision 0) +++ gcc/testsuite/gcc.dg/pr52549.c (revision 0) @@ -0,0 +1,6 @@ +/* { dg-do compile } */ + +_mark (long obj, int i, char *a) +{ + (char *)&(((long *)(obj)) [i]) - a; +}