PR c++/93173 - incorrect tree sharing.
authorJason Merrill <jason@redhat.com>
Fri, 10 Jan 2020 18:46:57 +0000 (13:46 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 10 Jan 2020 18:46:57 +0000 (13:46 -0500)
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

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/cp/typeck2.c
gcc/gimplify.c
gcc/gimplify.h
gcc/testsuite/g++.dg/cpp0x/initlist-new3.C [new file with mode: 0644]

index d054902d428f2d1815d96600f41f6d6ec3ad5b92..75c87718efa837bfe816f1dbc26515946a4c8d3e 100644 (file)
@@ -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
index 210ab4e619f5a544962a02e84d0180dbdd05d346..96bbcc9166ae9262c436f73a29661cae89859062 100644 (file)
@@ -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
index 827d240d11ad87fbebd11313a9e3bbb358a784ae..3d764bb6928968c517851ef451372aa47d60fe13 100644 (file)
@@ -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;
       }
index 955669727c354bca56c6457388788c312f7427cc..f36a5649ae65b63c53be034635bdcc2fa9e535c9 100644 (file)
@@ -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);
        }
     }
index 4243d3a83b849dda3c66e6b23fb0af8010480352..00d264fc90f405ca17ff7888e92c89cceb69637d 100644 (file)
@@ -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);
index 9f4e33232e39578e92d193721382821d31c0a2a4..9bb8c67b5930a44bc3471e05cca1fad8d579c746 100644 (file)
@@ -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 (file)
index 0000000..04a8f5c
--- /dev/null
@@ -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}; }