aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-01-10 13:46:57 -0500
committerJason Merrill <jason@gcc.gnu.org>2020-01-10 13:46:57 -0500
commit640b23d7ff5f3fad005dcbfb04a36e27000fc150 (patch)
tree61f43978030d8d42b472bfc871aed800deaa0e66
parent9b0700571fe390afcca32dcb3b2122640e628c95 (diff)
downloadgcc-640b23d7ff5f3fad005dcbfb04a36e27000fc150.zip
gcc-640b23d7ff5f3fad005dcbfb04a36e27000fc150.tar.gz
gcc-640b23d7ff5f3fad005dcbfb04a36e27000fc150.tar.bz2
PR c++/93173 - incorrect tree sharing.
My patch for 93033 wasn't sufficient to handle all the possible sharing introduced by split_nonconstant_init, and it occurred to me that it would make sense to use the same unsharing technique as unshare_body, namely copy_if_shared. PR c++/93033 gcc/ * gimplify.c (copy_if_shared): No longer static. * gimplify.h: Declare it. gcc/cp/ * cp-gimplify.c (cp_gimplify_init_expr, cp_gimplify_expr): Use copy_if_shared after cp_genericize_tree. * typeck2.c (split_nonconstant_init): Don't unshare here. From-SVN: r280126
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-gimplify.c2
-rw-r--r--gcc/cp/typeck2.c4
-rw-r--r--gcc/gimplify.c2
-rw-r--r--gcc/gimplify.h1
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-new3.C13
7 files changed, 32 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d054902..75c87718 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-01-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/93173 - incorrect tree sharing.
+ * gimplify.c (copy_if_shared): No longer static.
+ * gimplify.h: Declare it.
+
2020-01-10 Richard Sandiford <richard.sandiford@arm.com>
* doc/invoke.texi (-msve-vector-bits=): Document that
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 210ab4e..96bbcc9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2020-01-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/93173 - incorrect tree sharing.
+ PR c++/93033
+ * cp-gimplify.c (cp_gimplify_init_expr, cp_gimplify_expr): Use
+ copy_if_shared after cp_genericize_tree.
+ * typeck2.c (split_nonconstant_init): Don't unshare here.
+
2020-01-08 Jason Merrill <jason@redhat.com>
* cp-gimplify.c (cp_gimplify_expr) [TARGET_EXPR]: Check
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 827d240..3d764bb 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -537,6 +537,7 @@ cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p)
replace_placeholders (from, to);
from = split_nonconstant_init (to, from);
cp_genericize_tree (&from, false);
+ copy_if_shared (&from);
*expr_p = from;
return;
}
@@ -712,6 +713,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
hash_set<tree> pset;
cp_walk_tree (expr_p, cp_fold_r, &pset, NULL);
cp_genericize_tree (expr_p, false);
+ copy_if_shared (expr_p);
ret = GS_OK;
input_location = loc;
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 9556697..f36a564 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -34,7 +34,6 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "gcc-rich-location.h"
#include "target.h"
-#include "gimplify.h"
static tree
process_init_constructor (tree type, tree init, int nested, int flags,
@@ -792,8 +791,7 @@ split_nonconstant_init (tree dest, tree init)
}
else if (init)
{
- tree ie = build2 (INIT_EXPR, void_type_node,
- unshare_expr (dest), init);
+ tree ie = build2 (INIT_EXPR, void_type_node, dest, init);
code = add_stmt_to_compound (ie, code);
}
}
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 4243d3a..00d264f 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -937,7 +937,7 @@ copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
/* Unshare most of the shared trees rooted at *TP. DATA is passed to the
copy_if_shared_r callback unmodified. */
-static inline void
+void
copy_if_shared (tree *tp, void *data)
{
walk_tree (tp, copy_if_shared_r, data, NULL);
diff --git a/gcc/gimplify.h b/gcc/gimplify.h
index 9f4e332..9bb8c67 100644
--- a/gcc/gimplify.h
+++ b/gcc/gimplify.h
@@ -62,6 +62,7 @@ extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq * = NULL,
extern void declare_vars (tree, gimple *, bool);
extern void gimple_add_tmp_var (tree);
extern void gimple_add_tmp_var_fn (struct function *, tree);
+extern void copy_if_shared (tree *, void * = NULL);
extern tree unshare_expr (tree);
extern tree unshare_expr_without_location (tree);
extern tree voidify_wrapper_expr (tree, tree);
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-new3.C b/gcc/testsuite/g++.dg/cpp0x/initlist-new3.C
new file mode 100644
index 0000000..04a8f5c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-new3.C
@@ -0,0 +1,13 @@
+// PR c++/93173
+// { dg-do compile { target c++11 } }
+
+template<typename> struct S1 {
+ S1(S1 &);
+ ~S1();
+};
+struct S2 {
+ S1<void> x;
+ int y;
+ int z;
+};
+void f(S1<void> x, int y, int z) { new S2{x, y, z}; }