On Thu, Mar 15, 2018 at 01:15:53PM -0400, Jason Merrill wrote:
> > 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.
Seems the gimplify.c stuff:
case INDIRECT_REF:
{
/* If we have code like
*(const A*)(A*)&x
where the type of "x" is a (possibly cv-qualified variant
of "A"), treat the entire expression as identical to "x".
This kind of code arises in C++ when an object is bound
to a const reference, and if "x" is a TARGET_EXPR we want
to take advantage of the optimization below. */
...
has been added in r92539 as part of PR16405 fix. So, do we want to stop
doing that unconditionally if t is a TARGET_EXPR, or for selected kinds of
types of TARGET_EXPR, or ask some langhook whether it is ok to do so
(say not ok if find_placeholders (t))? Or contains_placeholder_p?
Though the last one could also affect Ada and could return true even if
the PLACEHOLDER_EXPRs are for some nested TARGET_EXPR in it.
> So the existing call to replace_placeholders in build_over_call is wrong.
Shall it be just dropped if we tweak the gimplifier somehow?
> 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.
Jakub