Hi! This ICE is because c_finish_return calls convert after c_fully_fold is performed on the argument, and doesn't call it again, thus we need in_late_binary_op.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.7? 2012-09-13 Jakub Jelinek <ja...@redhat.com> PR c/54559 * c-typeck.c (c_finish_return): Do convert to BOOLEAN_TYPE or COMPLEX_TYPE with in_late_binary_op set temporarily to true. * gcc.c-torture/compile/pr54559.c: New test. --- gcc/c/c-typeck.c.jj 2012-09-12 10:56:59.000000000 +0200 +++ gcc/c/c-typeck.c 2012-09-13 10:57:24.318837832 +0200 @@ -8682,12 +8682,18 @@ c_finish_return (location_t loc, tree re npc, NULL_TREE, NULL_TREE, 0); tree res = DECL_RESULT (current_function_decl); tree inner; + bool save; current_function_returns_value = 1; if (t == error_mark_node) return NULL_TREE; + save = in_late_binary_op; + if (TREE_CODE (TREE_TYPE (res)) == BOOLEAN_TYPE + || TREE_CODE (TREE_TYPE (res)) == COMPLEX_TYPE) + in_late_binary_op = true; inner = t = convert (TREE_TYPE (res), t); + in_late_binary_op = save; /* Strip any conversions, additions, and subtractions, and see if we are returning the address of a local variable. Warn if so. */ --- gcc/testsuite/gcc.c-torture/compile/pr54559.c.jj 2012-09-13 11:23:32.049954011 +0200 +++ gcc/testsuite/gcc.c-torture/compile/pr54559.c 2012-09-13 11:23:15.000000000 +0200 @@ -0,0 +1,9 @@ +/* PR c/54559 */ + +typedef double _Complex T; + +T +foo (double x, double y) +{ + return x + y * (T) (__extension__ 1.0iF); +} Jakub