From: Jason Merrill Date: Mon, 5 Dec 2011 15:49:34 +0000 (-0500) Subject: * init.c (expand_default_init): Unshare args in ctor delegation. X-Git-Tag: releases/gcc-4.7.0~1760 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c4ce224c4b344c31347e526a4f8825c4daa414bd;p=thirdparty%2Fgcc.git * init.c (expand_default_init): Unshare args in ctor delegation. From-SVN: r182013 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index be5ebea1a3d4..fe4696bf2050 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2011-12-05 Jason Merrill + + * init.c (expand_default_init): Unshare args in ctor delegation. + 2011-12-05 Ville Voutilainen Pedro Lamarão diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 94bd34a2ce9c..8aa8285fa94f 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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 { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3bda000ffccb..dcc8226acdd5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-12-05 Jason Merrill + + * g++.dg/cpp0x/dc6.C: New. + 2011-12-05 Ville Voutilainen Pedro Lamarão diff --git a/gcc/testsuite/g++.dg/cpp0x/dc6.C b/gcc/testsuite/g++.dg/cpp0x/dc6.C new file mode 100644 index 000000000000..b16c0b47ba0d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/dc6.C @@ -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; +}