From c4ce224c4b344c31347e526a4f8825c4daa414bd Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 5 Dec 2011 10:49:34 -0500 Subject: * init.c (expand_default_init): Unshare args in ctor delegation. From-SVN: r182013 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/init.c | 27 ++++++++++++++++++++------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/cpp0x/dc6.C | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/dc6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index be5ebea..fe4696b 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 94bd34a..8aa8285 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 3bda000..dcc8226 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 0000000..b16c0b4 --- /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; +} -- cgit v1.1