------- Comment #5 from jakub at gcc dot gnu dot org 2007-12-13 00:08 ------- ret = GS_OK; } ret = GS_UNHANDLED; looks suspicious, but @@ -3492,6 +3492,7 @@ gimplify_modify_expr_rhs (tree *expr_p, { *from_p = DECL_INITIAL (*from_p); ret = GS_OK; + break; } ret = GS_UNHANDLED; break; doesn't cure this. But if you prevent this optimization whenever gimplify_init_constructor would: if (valid_const_initializer && num_nonzero_elements > 1 && TREE_READONLY (object) && TREE_CODE (object) == VAR_DECL) or if (size > 0 && !can_move_by_pieces (size, align)) then this bug will go away.
BTW, in addition to the volatile check suggested by Mark, shouldn't it test also !TREE_SIDE_EFFECTS (DECL_INITIAL (...)))? Otherwise: struct A { int i, j; }; static struct A a, b; int foo (int x, int y) { const struct A i = { x++, y++ }; a = i; b = i; return x + y; } could evaluate multiple times. Actually this is a wrong example, because i here was already gimplified and while for constant initializer gimplify_init_constructor puts DECL_INITIAL back (valid_const_initializer && && num_nonzero_elements > 1 && TREE_READONLY (object) && TREE_CODE (object) == VAR_DECL case), for non-constant DECL_INITIAL will be NULL. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34448