diff mbox

[committed] Fix a tree sharing bug during gimplification (PR c/79089)

Message ID 20170116213737.GS1867@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Jan. 16, 2017, 9:37 p.m. UTC
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  <jakub@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.


	Jakub
diff mbox

Patch

--- 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) {}; });
+}