From: Jason Merrill Date: Sat, 9 Feb 2008 03:40:14 +0000 (-0500) Subject: re PR c++/35116 (Fail to compile valid code) X-Git-Tag: releases/gcc-4.3.0~226 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7efc22ea0178308410921d93e9a6c5ea4c9ac282;p=thirdparty%2Fgcc.git re PR c++/35116 (Fail to compile valid code) PR c++/35116 * tree.c (build_target_expr_with_type): Handle void initializer. (bot_manip): Remap slot before recursing. From-SVN: r132197 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9fdd55be2481..da9668da2ad6 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 b14462fd3394..e893442be422 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 000000000000..fbe166471264 --- /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); +}