OSDN Git Service

* init.c (expand_default_init): Unshare args in ctor delegation.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Dec 2011 15:49:34 +0000 (15:49 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 5 Dec 2011 15:49:34 +0000 (15:49 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182013 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/dc6.C [new file with mode: 0644]

index be5ebea..fe4696b 100644 (file)
@@ -1,3 +1,7 @@
+2011-12-05  Jason Merrill  <jason@redhat.com>
+
+       * init.c (expand_default_init): Unshare args in ctor delegation.
+
 2011-12-05  Ville Voutilainen  <ville.voutilainen@gmail.com>
            Pedro LamarĂ£o  <pedro.lamarao@gmail.com>
 
index 94bd34a..8aa8285 100644 (file)
@@ -1619,17 +1619,30 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
       /* Delegating constructor. */
       tree complete;
       tree base;
+      tree elt; unsigned i;
+
+      /* Unshare the arguments for the second call.  */
+      VEC(tree,gc) *parms2 = make_tree_vector ();
+      FOR_EACH_VEC_ELT (tree, parms, i, elt)
+       {
+         elt = break_out_target_exprs (elt);
+         VEC_safe_push (tree, gc, parms2, elt);
+       }
       complete = build_special_member_call (exp, complete_ctor_identifier,
-                                       &parms, binfo, flags,
-                                       complain);
+                                           &parms2, binfo, flags,
+                                           complain);
+      complete = fold_build_cleanup_point_expr (void_type_node, complete);
+      release_tree_vector (parms2);
+
       base = build_special_member_call (exp, base_ctor_identifier,
                                        &parms, binfo, flags,
                                        complain);
-      rval = build3 (COND_EXPR, TREE_TYPE (complete),
-                   build2 (EQ_EXPR, boolean_type_node,
-                           current_in_charge_parm, integer_zero_node),
-                   base,
-                   complete);
+      base = fold_build_cleanup_point_expr (void_type_node, base);
+      rval = build3 (COND_EXPR, void_type_node,
+                    build2 (EQ_EXPR, boolean_type_node,
+                            current_in_charge_parm, integer_zero_node),
+                    base,
+                    complete);
     }
    else
     {
index 3bda000..dcc8226 100644 (file)
@@ -1,3 +1,7 @@
+2011-12-05  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/dc6.C: New.
+
 2011-12-05  Ville Voutilainen  <ville.voutilainen@gmail.com>
            Pedro LamarĂ£o <pedro.lamarao@gmail.com>
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/dc6.C b/gcc/testsuite/g++.dg/cpp0x/dc6.C
new file mode 100644 (file)
index 0000000..b16c0b4
--- /dev/null
@@ -0,0 +1,40 @@
+// { dg-do run { target c++11 } }
+
+int a_ct;
+
+struct A
+{
+  A(int i): i(i) { ++a_ct; }
+  A(const A& a): i(a.i) { ++a_ct; }
+  ~A() { --a_ct; }
+  int i;
+};
+
+struct V
+{
+  V() { }
+};
+
+struct B: virtual V
+{
+  A a;
+  B(A a): a(a) { }
+  B(int i): B(A(i)) { }
+};
+
+struct C: B
+{
+  C(int i): B(i) { }
+};
+
+int main()
+{
+  {
+    B b(42);
+    C c(24);
+    if (b.a.i != 42
+       ||c.a.i != 24)
+      __builtin_abort ();
+  }
+  return a_ct;
+}