On Thu, Mar 15, 2018 at 4:32 AM, Jakub Jelinek <ja...@redhat.com> wrote: > On Wed, Mar 14, 2018 at 08:55:47PM -0400, Jason Merrill wrote: >> > @@ -3192,16 +3198,70 @@ replace_placeholders (tree exp, tree obj >> > return exp; >> > >> > tree *tp = &exp; >> > - hash_set<tree> pset; >> > - replace_placeholders_t data = { obj, false, &pset }; >> > + /* Use exp instead of *(type *)&exp. */ >> > + while (TREE_CODE (exp) == INDIRECT_REF) >> > + { >> > + tree t = TREE_OPERAND (exp, 0); >> > + STRIP_NOPS (t); >> > + if (TREE_CODE (t) == ADDR_EXPR >> > + && (t = TREE_OPERAND (t, 0)) >> > + && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (exp), >> > + TREE_TYPE (t))) >> > + exp = t; >> > + else >> > + break; >> > + } >> >> What's the motivation for this? > > g++.dg/cpp0x/nsdmi13.C ICEs without that, we have there: > a = A({}); > and build_over_call does: > 8163 else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE > (as_base))) > 8164 { > 8165 arg = cp_build_fold_indirect_ref (arg); > 8166 val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg); > 8167 /* Handle NSDMI that refer to the object being initialized. > */ > 8168 replace_placeholders (arg, to); > 8169 } > where arg is after the cp_build_fold_indirect_ref > *(struct A &) &TARGET_EXPR <D.2403, {.p=&<PLACEHOLDER_EXPR struct A>}> > This is in MODIFY_EXPR rather than INIT_EXPR and the gimplifier through > gimple_fold_indirect_ref_rhs folds the *(struct A &) & away and so there is > no further temporary and thus cp_gimplify_init_expr isn't called to > replace_placeholders, so if we don't replace it here (with to being the a > VAR_DECL), we don't replace it ever.
Ah. That's a problem: the language says there's a temporary, so after the assignment a.p should not point to a. So the existing call to replace_placeholders in build_over_call is wrong. Seems like if the initializer for a TARGET_EXPR involves PLACEHOLDER_EXPR, the gimple_fold_modify_expr_rhs treatment of TARGET_EXPR isn't safe for MODIFY_EXPR, for the same reason that cp_gimplify_expr treats INIT_EXPR and MODIFY_EXPR differently. Jason