On 2/11/19 6:03 PM, Marek Polacek wrote:
On Mon, Feb 11, 2019 at 01:43:36PM -0500, Jason Merrill wrote:
On 2/7/19 6:02 PM, Marek Polacek wrote:
Since r268321 we can call digest_init even in a template, when the compound
literal isn't instantiation-dependent.

Right.  And since digest_init modifies the CONSTRUCTOR in place, that means
the template trees are digested rather than the original parse trees that we
try to use.  If we're going to use digest_init, we should probably save
another CONSTRUCTOR with the original trees.

I tried unsharing the constructor and even its contents but only then did I
realize that this cannot work.

Why wouldn't going back to saving {*((struct S *) this)->r} work?

It's not digest_init that adds the problematic
INDIRECT_REF via convert_from_reference, it's instantiate_pending_templates
-> tsubst_expr -> ... -> finish_non_static_data_member.

So the problem isn't sharing the contents of the CONSTRUCTOR, but rather what
finish_non_static_data_member does with the

   {.r=(struct R &) (struct R *) ((struct S *) this)->r}

expression.  The same problem would appear even before r268321 changes if we
called tsubst_* twice on the CONSTRUCTOR above.

Yes, it sounds like there's a bug in that path as well. Perhaps tsubst_copy_and_build/COMPONENT_REF should strip a REFERENCE_REF_P if t was already a reference.

Do you still think digest_init and/or finish_compound_literal need tweaking?

I imagine that saving post-digest trees might cause other problems, but perhaps not. Perhaps we ought to move away more generally from trying to save the original parse trees for non-dependent expressions and messing with NON_DEPENDENT_EXPR.

Jason

Reply via email to