https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79937
--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> --- That said, I've tried: --- gcc/cp/semantics.c.jj 2018-03-06 08:01:37.851883447 +0100 +++ gcc/cp/semantics.c 2018-03-06 15:19:27.685013764 +0100 @@ -2814,6 +2814,11 @@ finish_compound_literal (tree type, tree if (!VECTOR_TYPE_P (type)) compound_literal = get_target_expr_sfinae (compound_literal, complain); + if (TREE_CODE (compound_literal) == TARGET_EXPR) + compound_literal + = replace_placeholders (compound_literal, + TARGET_EXPR_SLOT (compound_literal)); + return compound_literal; } instead, but that fails miserably during gimplification, seems we optimize away those TARGET_EXPRs at some point just to their TARGET_EXPR_INITIAL and referring in that CONSTRUCTOR to the TARGET_EXPR_SLOT then doesn't really work. The regression was introduced by the: - case TARGET_EXPR: - /* Don't mess with placeholders in an unrelated object. */ - *walk_subtrees = false; - break; replace_placeholders_r change, which makes me wonder if replace_placeholders could somehow make a difference between TARGET_EXPRs it wants to walk into (e.g. the TARGET_EXPR created in nsdmi-aggr3.C: #0 make_node (code=TARGET_EXPR) at ../../gcc/tree.c:1056 #1 0x00000000015d4974 in build4 (code=TARGET_EXPR, tt=<record_type 0x7fffefd9fd20 A>, arg0=<var_decl 0x7fffefdbd360>, arg1=<aggr_init_expr 0x7fffefdb4600>, arg2=<tree 0x0>, arg3=<tree 0x0>) at ../../gcc/tree.c:4797 #2 0x0000000000ace5e4 in build_target_expr (decl=<var_decl 0x7fffefdbd360>, value=<aggr_init_expr 0x7fffefdb4600>, complain=3) at ../../gcc/cp/tree.c:454 #3 0x0000000000acf39c in build_cplus_new (type=<record_type 0x7fffefd9fd20 A>, init=<aggr_init_expr 0x7fffefdb4440>, complain=3) at ../../gcc/cp/tree.c:631 #4 0x0000000000ad8b16 in bot_manip (tp=0x7fffffffc3c8, walk_subtrees=0x7fffffffc37c, data=0x2dd3c80) at ../../gcc/cp/tree.c:2915 #5 0x00000000015f02f2 in walk_tree_1 (tp=0x7fffffffc3c8, func=0xad89ae <bot_manip(tree*, int*, void*)>, data=0x2dd3c80, pset=0x0, lh=0xae085b <cp_walk_subtrees(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*)>) at ../../gcc/tree.c:11400 #6 0x0000000000ad94e2 in break_out_target_exprs (t=<target_expr 0x7fffefc510a8>) at ../../gcc/cp/tree.c:3050 #7 0x000000000093e0f2 in get_nsdmi (member=<field_decl 0x7fffefd6dab0 a>, in_ctor=false, complain=3) at ../../gcc/cp/init.c:637 and the TARGET_EXPRs created by finish_compound_literal by the testcase included in the above patch or the: // PR c++/79937 // { dg-do run { target c++14 } } struct X { unsigned i; unsigned n = i; unsigned m = i; }; X bar (X x) { if (x.i != 1 || x.n != 2 || x.m != 1) __builtin_abort (); return x; } int main () { X x = bar (X {1, X {2}.n}); if (x.i != 1 || x.n != 2 || x.m != 1) __builtin_abort (); } E.g. could we walk into TARGET_EXPRs that have TARGET_EXPR_INITIAL AGGR_INIT_EXPR, but avoid those that have TARGET_EXPR_INITIAL a CONSTRUCTOR, or a CONSTRUCTOR with certain flags, or have some flags on TARGET_EXPRs? Tried: --- gcc/cp/tree.c.jj 2018-03-06 08:01:37.851883447 +0100 +++ gcc/cp/tree.c 2018-03-06 16:07:53.296061505 +0100 @@ -3165,6 +3165,13 @@ replace_placeholders_r (tree* t, int* wa break; } + case TARGET_EXPR: + /* Don't mess with placeholders in finish_compound_literal + created TARGET_EXPRs. */ + if (TREE_CODE (TARGET_EXPR_INITIAL (*t)) == CONSTRUCTOR) + *walk_subtrees = false; + break; + default: if (d->pset->add (*t)) *walk_subtrees = false; but that FAILs nsdmi13.C, where the TARGET_EXPR is created by: #4 0x00000000015c5ff9 in make_node (code=TARGET_EXPR) at ../../gcc/tree.c:1053 #5 0x00000000015d49ca in build4 (code=TARGET_EXPR, tt=<record_type 0x7fffefd9f9d8 A>, arg0=<var_decl 0x7fffefdb8480>, arg1=<constructor 0x7fffefdb32b8>, arg2=<tree 0x0>, arg3=<tree 0x0>) at ../../gcc/tree.c:4797 #6 0x0000000000ace5e4 in build_target_expr (decl=<var_decl 0x7fffefdb8480>, value=<constructor 0x7fffefdb32b8>, complain=3) at ../../gcc/cp/tree.c:454 #7 0x0000000000acfaee in force_target_expr (type=<record_type 0x7fffefd9f9d8 A>, init=<constructor 0x7fffefdb32b8>, complain=3) at ../../gcc/cp/tree.c:782 #8 0x0000000000acfa92 in build_target_expr_with_type (init=<constructor 0x7fffefdb32b8>, type=<record_type 0x7fffefd9f9d8 A>, complain=3) at ../../gcc/cp/tree.c:766 #9 0x0000000000acfc0e in get_target_expr_sfinae (init=<constructor 0x7fffefdb32b8>, complain=3) at ../../gcc/cp/tree.c:797 #10 0x0000000000821df6 in convert_like_real (convs=0x2e5f280, expr=<constructor 0x7fffefdb32b8>, fn=<function_decl 0x7fffefdb6900 __ct_comp >, argnum=0, issue_conversion_warnings=true, c_cast_p=false, complain=3) at ../../gcc/cp/call.c:6902 #11 0x0000000000821ede in convert_like_real (convs=0x2e5f2b0, expr=<constructor 0x7fffefdb32b8>, fn=<function_decl 0x7fffefdb6900 __ct_comp >, argnum=0, issue_conversion_warnings=true, c_cast_p=false, complain=3) at ../../gcc/cp/call.c:6912 #12 0x0000000000826426 in build_over_call (cand=0x2e5f2e0, flags=1, complain=3) at ../../gcc/cp/call.c:7945 #13 0x000000000082d3fb in build_new_method_call_1 (instance=<indirect_ref 0x7fffefdb2dc0>, fns=<overload 0x7fffefdb2940>,