[backport from gcc-4.7/trunk r180442 ] gcc/cp/ 2011-10-25 Jason Merrill PR c++/50866 PR c++/41449 * semantics.c (maybe_cleanup_point_expr_void): No longer static. * typeck2.c (split_nonconstant_init_1): Use it. * cp-tree.h: Declare it. * decl.c (wrap_cleanups_r): Stop at CLEANUP_POINT_EXPR. gcc/testsuite/ 2011-10-25 Jason Merrill PR c++/50866 * g++.dg/init/aggr7.C: New. --- gcc-4.6.3/gcc/cp/cp-tree.h.~1~ 2011-09-25 22:29:04.000000000 +0200 +++ gcc-4.6.3/gcc/cp/cp-tree.h 2012-03-04 18:44:19.000000000 +0100 @@ -5212,6 +5212,7 @@ extern int stmts_are_full_exprs_p (void extern void init_cp_semantics (void); extern tree do_poplevel (tree); extern void add_decl_expr (tree); +extern tree maybe_cleanup_point_expr_void (tree); extern tree finish_expr_stmt (tree); extern tree begin_if_stmt (void); extern void finish_if_stmt_cond (tree, tree); --- gcc-4.6.3/gcc/cp/decl.c.~1~ 2012-02-15 00:34:34.000000000 +0100 +++ gcc-4.6.3/gcc/cp/decl.c 2012-03-04 18:44:19.000000000 +0100 @@ -5584,7 +5584,9 @@ make_rtl_for_nonlocal_decl (tree decl, t static tree wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data) { - if (TYPE_P (*stmt_p)) + /* Stop at types or full-expression boundaries. */ + if (TYPE_P (*stmt_p) + || TREE_CODE (*stmt_p) == CLEANUP_POINT_EXPR) { *walk_subtrees = 0; return NULL_TREE; --- gcc-4.6.3/gcc/cp/semantics.c.~1~ 2012-02-09 18:17:36.000000000 +0100 +++ gcc-4.6.3/gcc/cp/semantics.c 2012-03-04 18:44:19.000000000 +0100 @@ -423,7 +423,7 @@ maybe_cleanup_point_expr (tree expr) expression. The reason why we do this is because the original type might be an aggregate and we cannot create a temporary variable for that type. */ -static tree +tree maybe_cleanup_point_expr_void (tree expr) { if (!processing_template_decl && stmts_are_full_exprs_p ()) --- gcc-4.6.3/gcc/cp/typeck2.c.~1~ 2012-03-04 18:41:16.000000000 +0100 +++ gcc-4.6.3/gcc/cp/typeck2.c 2012-03-04 18:44:19.000000000 +0100 @@ -553,6 +553,7 @@ split_nonconstant_init_1 (tree dest, tre code = build2 (INIT_EXPR, inner_type, sub, value); code = build_stmt (input_location, EXPR_STMT, code); + code = maybe_cleanup_point_expr_void (code); add_stmt (code); if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type)) { --- gcc-4.6.3/gcc/testsuite/g++.dg/init/aggr7.C.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.3/gcc/testsuite/g++.dg/init/aggr7.C 2012-03-04 18:44:19.000000000 +0100 @@ -0,0 +1,13 @@ +// PR c++/50866 + +struct A { A(); ~A(); }; +struct B { B(const char *, const A& = A()); ~B(); }; +struct C { + B b1, b2; +}; +void f() +{ + C c = { + "a","b" + }; +}