I have reduced the original application down to a small reproducer. The following code fails to compile. It works with gcc 4.3.0, intel (icc), sun (cc), and pathscale (pathcc). PGI's pgcc also generates an ICE with the function and I'll submit the bug to them as well. void foo (void) { _Bool d; long double _Complex *s; d = *s++; } When you try to compile with gcc version 4.5.1. It generates an error: foo.c: In function 'foo': foo.c:5:7: internal compiler error: in gimplify_expr, at gimplify.c:7137 My full output from gcc -v... is: Using built-in specs. COLLECT_GCC=/usr/local/apps/gnu/4.5.1/bin/gcc COLLECT_LTO_WRAPPER=/usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.5.1/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../gcc-4.5.1/configure --prefix=/usr/apps/gnu/4.5.1 --with-mpfr-include=/usr/apps/gnu/4.5.1/include --with-mpfr-lib=/usr/apps/gnu/4.5.1/lib --with-libelf=/usr/apps/gnu/4.5.1 --disable-multilib --with-gmp=/usr/apps/gnu/4.5.1/lib --with-gmp-include=/usr/apps/gnu/4.5.1/include --enable-languages=c,c++,fortran,java,objc --enable-lto Thread model: posix gcc version 4.5.1 (GCC) COLLECT_GCC_OPTIONS='-c' '-v' '-save-temps' '-mtune=generic' '-march=x86-64' /usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.5.1/cc1 -E -quiet -v -iprefix /usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.1/ foo.c -mtune=generic -march=x86-64 -fpch-preprocess -o foo.i ignoring nonexistent directory "/usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.1/../../../../x86_64-unknown-linux-gnu/include" ignoring duplicate directory "/usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.5.1/include" ignoring duplicate directory "/usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.5.1/include-fixed" ignoring nonexistent directory "/usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../lib/gcc/../../lib/gcc/x86_64-unknown-linux-gnu/4.5.1/../../../../x86_64-unknown-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.1/include /usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.1/include-fixed /usr/local/include /usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../lib/gcc/../../include /usr/include End of search list. COLLECT_GCC_OPTIONS='-c' '-v' '-save-temps' '-mtune=generic' '-march=x86-64' /usr/gapps/opnsrc/gnu/dev/lnx-2.5-o/4.5.1/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.5.1/cc1 -fpreprocessed foo.i -quiet -dumpbase foo.c -mtune=generic -march=x86-64 -auxbase foo -version -o foo.s GNU C (GCC) version 4.5.1 (x86_64-unknown-linux-gnu) compiled by GNU C version 4.5.1, GMP version 4.2.2, MPFR version 2.4.2, MPC version 0.8.1 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C (GCC) version 4.5.1 (x86_64-unknown-linux-gnu) compiled by GNU C version 4.5.1, GMP version 4.2.2, MPFR version 2.4.2, MPC version 0.8.1 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 59090c9e0e8cd3d0437c78809f831ff7 foo.c: In function 'foo': foo.c:5:7: internal compiler error: in gimplify_expr, at gimplify.c:7137
Confirmed.
<<< Unknown tree: c_maybe_const_expr SAVE_EXPR <*s++ > >>>
Any complex type will cause this ICE.
The problem is that c_fully_fold_internal doesn't recurse on the RHS of a MODIFY_EXPR: /* The RHS of a MODIFY_EXPR was fully folded when building that expression for the sake of conversion warnings. */ While this is true, here RHS was INDIRECT_REF of a POSTINCREMENT_EXPR of PARM_DECL, all with COMPLEX_TYPE or pointers to that and it was fully folded. But afterwards when this RHS is convert()ed to the LHS type, c_common_truthvalue_conversion is called and introduces new C_MAYBE_CONST_EXPRs into it. I wonder if we couldn't swap the order of c_fully_fold and convert_for_assignment in build_modify_expr: newrhs = c_fully_fold (newrhs, false, NULL); if (rhs_semantic_type) newrhs = build1 (EXCESS_PRECISION_EXPR, rhs_semantic_type, newrhs); newrhs = convert_for_assignment (location, lhstype, newrhs, rhs_origtype, ic_assign, npc, NULL_TREE, NULL_TREE, 0); so that it would be fully folding also whatever was added by convert_for_assignment. Joseph?
Actually, reading that comment again it, the conversion warnings are probably emitted during convert_for_assignment and thus the earlier c_fully_fold is needed. Perhaps we need another c_fully_fold if convert_for_assignment returned something different from the passed argument, or remove the if (code != MODIFY_EXPR) guard for c_fully_fold_internal on the RHS of a MODIFY_EXPR.
My inclination is that the problem is a missing check of in_late_binary_op. Specifically, that c_common_truthvalue_conversion should call save_expr instead of c_save_expr if in_late_binary_op (which in turn requires that in_late_binary_op move from c-tree.h/c-typeck.c to being defined/declared in c-family code).
It is caused by revision 46547: http://gcc.gnu.org/ml/gcc-cvs/2009-03/msg00761.html
It is caused by revision 145254: http://gcc.gnu.org/ml/gcc-cvs/2009-03/msg00761.html
Testing a patch.
Author: jsm28 Date: Fri Nov 19 18:32:57 2010 New Revision: 166951 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166951 Log: PR c/46547 * c-tree.h (in_late_binary_op): Move to c-family/c-common.h. * c-typeck.c (in_late_binary_op): Move to c-family/c-common.c. c-family: * c-common.c (in_late_binary_op): Define. (c_common_truthvalue_conversion): Check in_late_binary_op before calling c_save_expr. * c-common.h (in_late_binary_op): Declare. testsuite: * gcc.c-torture/compile/pr46547-1.c: New test. Added: trunk/gcc/testsuite/gcc.c-torture/compile/pr46547-1.c Modified: trunk/gcc/ChangeLog trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c-common.c trunk/gcc/c-family/c-common.h trunk/gcc/c-tree.h trunk/gcc/c-typeck.c trunk/gcc/testsuite/ChangeLog
Author: jsm28 Date: Fri Nov 19 20:45:00 2010 New Revision: 166957 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166957 Log: PR c/46547 * c-common.c (in_late_binary_op): Define. (c_common_truthvalue_conversion): Check in_late_binary_op before calling c_save_expr. * c-common.h (in_late_binary_op): Declare. * c-tree.h (in_late_binary_op): Move to c-common.h. * c-typeck.c (in_late_binary_op): Move to c-common.c. testsuite: * gcc.c-torture/compile/pr46547-1.c: New test. Added: branches/gcc-4_5-branch/gcc/testsuite/gcc.c-torture/compile/pr46547-1.c Modified: branches/gcc-4_5-branch/gcc/ChangeLog branches/gcc-4_5-branch/gcc/c-common.c branches/gcc-4_5-branch/gcc/c-common.h branches/gcc-4_5-branch/gcc/c-tree.h branches/gcc-4_5-branch/gcc/c-typeck.c branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
Fixed for 4.5.2 and 4.6.
Revision 166951 breaks bootstrap with obj-c++ enabled: ld: duplicate symbol _in_late_binary_op in c-family/c-common.o and objcp/objcp-act.o
Author: jakub Date: Fri Nov 19 23:44:47 2010 New Revision: 166964 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166964 Log: PR c/46547 * objc-act.c (in_late_binary_op): Remove. Modified: trunk/gcc/objc/ChangeLog trunk/gcc/objc/objc-act.c
Author: jakub Date: Fri Nov 19 23:46:57 2010 New Revision: 166965 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166965 Log: PR c/46547 * objc-act.c (in_late_binary_op): Remove. Modified: branches/gcc-4_5-branch/gcc/objc/ChangeLog branches/gcc-4_5-branch/gcc/objc/objc-act.c