aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-01-03 17:10:56 -0500
committerJason Merrill <jason@gcc.gnu.org>2020-01-03 17:10:56 -0500
commit8b5d34fc0687dcf53c80c7fa2baa285ebf753708 (patch)
treedf4d4e3be118895b7402e47c1672c49f6a4402b5
parent657fea973b000000350c99de9e67bff0438d1503 (diff)
downloadgcc-8b5d34fc0687dcf53c80c7fa2baa285ebf753708.zip
gcc-8b5d34fc0687dcf53c80c7fa2baa285ebf753708.tar.gz
gcc-8b5d34fc0687dcf53c80c7fa2baa285ebf753708.tar.bz2
PR c++/93033 - incorrect tree node sharing with array init.
The split_nonconstant_init piece is the only one necessary to fix the testcase, but it occurred to me that we might as well not split when -fno-exceptions. * typeck2.c (split_nonconstant_init): Unshare non-decl. * cp-gimplify.c (cp_gimplify_init_expr): Only split if -fexceptions. From-SVN: r279871
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-gimplify.c1
-rw-r--r--gcc/cp/typeck2.c4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist-array9.C20
4 files changed, 30 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9b607b2..421048b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2020-01-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/93033 - incorrect tree node sharing with array init.
+ * typeck2.c (split_nonconstant_init): Unshare non-decl.
+ * cp-gimplify.c (cp_gimplify_init_expr): Only split if -fexceptions.
+
2020-01-02 Jason Merrill <jason@redhat.com>
* pt.c (invalid_nontype_parm_type_p): Reject class placeholder in
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 3eca359..eb55276 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -529,6 +529,7 @@ cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p)
/* If we might need to clean up a partially constructed object, break down
the CONSTRUCTOR with split_nonconstant_init. */
if (TREE_CODE (from) == CONSTRUCTOR
+ && flag_exceptions
&& TREE_SIDE_EFFECTS (from)
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (to)))
{
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index f36a564..9556697 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -34,6 +34,7 @@ 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,
@@ -791,7 +792,8 @@ split_nonconstant_init (tree dest, tree init)
}
else if (init)
{
- tree ie = build2 (INIT_EXPR, void_type_node, dest, init);
+ tree ie = build2 (INIT_EXPR, void_type_node,
+ unshare_expr (dest), init);
code = add_stmt_to_compound (ie, code);
}
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array9.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array9.C
new file mode 100644
index 0000000..4a5d74f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array9.C
@@ -0,0 +1,20 @@
+// PR c++/93033
+// { dg-do compile { target c++11 } }
+
+struct A {
+ A ();
+ ~A ();
+};
+
+A f();
+
+struct B {
+ A a;
+ bool b;
+};
+
+void
+foo ()
+{
+ B i[] { f() };
+}