diff options
author | Jason Merrill <jason@redhat.com> | 2011-12-05 10:49:34 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-12-05 10:49:34 -0500 |
commit | c4ce224c4b344c31347e526a4f8825c4daa414bd (patch) | |
tree | d6a5178d8190d03c6bec1e6047c5f9c554b93970 | |
parent | 238e471cadfb1c2995e6bc4c995328eacc39d0da (diff) | |
download | gcc-c4ce224c4b344c31347e526a4f8825c4daa414bd.zip gcc-c4ce224c4b344c31347e526a4f8825c4daa414bd.tar.gz gcc-c4ce224c4b344c31347e526a4f8825c4daa414bd.tar.bz2 |
* init.c (expand_default_init): Unshare args in ctor delegation.
From-SVN: r182013
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/init.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/dc6.C | 40 |
4 files changed, 68 insertions, 7 deletions
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 <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> 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 <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 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; +} |