Hi! gimplify_init_constructor sometimes uses object == lhs twice, once in gimple_build_assign and then as the result value, which is wrong if object is something that can't be shared such as COMPONENT_REF. Fixed by unsharing it in that case.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk. 2017-01-16 Jakub Jelinek <ja...@redhat.com> PR c/79089 * gimplify.c (gimplify_init_constructor): If want_value and object == lhs, unshare lhs to avoid invalid tree sharing. Formatting fix. * gcc.c-torture/compile/pr79089.c: New test. --- gcc/gimplify.c.jj 2017-01-05 11:43:11.000000000 +0100 +++ gcc/gimplify.c 2017-01-16 10:23:15.709864970 +0100 @@ -4586,8 +4586,8 @@ gimplify_init_constructor (tree *expr_p, } object = TREE_OPERAND (*expr_p, 0); - ctor = TREE_OPERAND (*expr_p, 1) = - optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1)); + ctor = TREE_OPERAND (*expr_p, 1) + = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1)); type = TREE_TYPE (ctor); elts = CONSTRUCTOR_ELTS (ctor); ret = GS_ALL_DONE; @@ -4911,6 +4911,8 @@ gimplify_init_constructor (tree *expr_p, { tree lhs = TREE_OPERAND (*expr_p, 0); tree rhs = TREE_OPERAND (*expr_p, 1); + if (want_value && object == lhs) + lhs = unshare_expr (lhs); gassign *init = gimple_build_assign (lhs, rhs); gimplify_seq_add_stmt (pre_p, init); } --- gcc/testsuite/gcc.c-torture/compile/pr79089.c.jj 2017-01-16 10:24:05.772227397 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr79089.c 2017-01-16 10:23:51.000000000 +0100 @@ -0,0 +1,12 @@ +/* PR c/79089 */ + +struct S { int b; }; +struct T { struct S c; } a; +int d; +struct S e; + +void +foo () +{ + e = ({ d++; a.c = (struct S) {}; }); +} Jakub