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

Reply via email to