From 40b708645595f059ae07a6fe1dbde72b26b2ef92 Mon Sep 17 00:00:00 2001 From: jason Date: Sat, 9 Feb 2008 03:40:14 +0000 Subject: [PATCH] PR c++/35116 * tree.c (build_target_expr_with_type): Handle void initializer. (bot_manip): Remap slot before recursing. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132197 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/tree.c | 12 +++++++----- gcc/testsuite/g++.dg/init/value2.C | 23 +++++++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/value2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9fdd55be248..da9668da2ad 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2008-02-08 Jason Merrill + + PR c++/35116 + * tree.c (build_target_expr_with_type): Handle void initializer. + (bot_manip): Remap slot before recursing. + 2008-02-06 Kaveh R. Ghazi PR other/35107 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index b14462fd339..e893442be42 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -415,10 +415,12 @@ build_target_expr_with_type (tree init, tree type) if (TREE_CODE (init) == TARGET_EXPR) return init; else if (CLASS_TYPE_P (type) && !TYPE_HAS_TRIVIAL_INIT_REF (type) + && !VOID_TYPE_P (TREE_TYPE (init)) && TREE_CODE (init) != COND_EXPR && TREE_CODE (init) != CONSTRUCTOR && TREE_CODE (init) != VA_ARG_EXPR) - /* We need to build up a copy constructor call. COND_EXPR is a special + /* We need to build up a copy constructor call. A void initializer + means we're being called from bot_manip. COND_EXPR is a special case because we already have copies on the arms and we don't want another one here. A CONSTRUCTOR is aggregate initialization, which is handled separately. A VA_ARG_EXPR is magic creation of an @@ -1468,17 +1470,17 @@ bot_manip (tree* tp, int* walk_subtrees, void* data) tree u; if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR) - u = build_cplus_new - (TREE_TYPE (t), break_out_target_exprs (TREE_OPERAND (t, 1))); + u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1)); else - u = build_target_expr_with_type - (break_out_target_exprs (TREE_OPERAND (t, 1)), TREE_TYPE (t)); + u = build_target_expr_with_type (TREE_OPERAND (t, 1), TREE_TYPE (t)); /* Map the old variable to the new one. */ splay_tree_insert (target_remap, (splay_tree_key) TREE_OPERAND (t, 0), (splay_tree_value) TREE_OPERAND (u, 0)); + TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1)); + /* Replace the old expression with the new version. */ *tp = u; /* We don't have to go below this point; the recursive call to diff --git a/gcc/testsuite/g++.dg/init/value2.C b/gcc/testsuite/g++.dg/init/value2.C new file mode 100644 index 00000000000..fbe16647126 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/value2.C @@ -0,0 +1,23 @@ +// PR c++/35116 +// Test that break_out_target_exprs works properly with complex +// value-initialization. + +struct A +{ + virtual void f (); +}; + +struct B +{ + A a; +}; + +struct C +{ + C (int, B = B()); +}; + +void f () +{ + C c (4); +} -- 2.11.4.GIT