From 98e92fb2104bcee038c0de4a116424b093001ae6 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Mon, 16 Jan 2017 22:35:30 +0100
Subject: [PATCH] re PR middle-end/79089 (error: incorrect sharing of tree
 nodes)

	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.

From-SVN: r244507
---
 gcc/ChangeLog                                 |  5 +++++
 gcc/gimplify.c                                |  6 ++++--
 gcc/testsuite/ChangeLog                       |  3 +++
 gcc/testsuite/gcc.c-torture/compile/pr79089.c | 12 ++++++++++++
 4 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr79089.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cc2e1d0c9f08..70f200be8831 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
 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.
+
 	PR target/79080
 	* loop-doloop.c (doloop_modify): Call unshare_all_rtl_in_chain on
 	sequence.  Formatting fixes.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e1e9ce9e9030..2777a23eb937 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -4586,8 +4586,8 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_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, gimple_seq *pre_p, gimple_seq *post_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);
     }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2ac159733c47..ef1fea51a877 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
 2017-01-16  Jakub Jelinek  <jakub@redhat.com>
 
+	PR c/79089
+	* gcc.c-torture/compile/pr79089.c: New test.
+
 	PR target/79080
 	* gcc.dg/pr79080.c: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr79089.c b/gcc/testsuite/gcc.c-torture/compile/pr79089.c
new file mode 100644
index 000000000000..523798824b6d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr79089.c
@@ -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) {}; });
+}
-- 
GitLab