On 2/16/19 8:23 PM, Marek Polacek wrote:
On Fri, Feb 15, 2019 at 01:59:10PM -1000, Jason Merrill wrote:
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?
Sorry, I misunderstood what you meant by "saving". I think I do now.
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.
With this patch, this seems no longer to be needed.
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.
Now that I've spent a lot of time looking into 89356 (and the other PRs broken
by the same revision), I'm convinced that we must return the original tree in
finish_compound_literal. But we still have to call digest_init or we lose
detecting narrowing conversions. What happens in that PR is that after
digest_init we lose the braced-init-list and that changes mangling. I've come
up with this fix for 89356, but it also fixes this PR, and likely all the
others.
The comments hopefully explain what I'm doing and why, the only suspicious
thing is the get_target_expr_sfinae call, that is so that initlist109.C
keeps compiling; without the call to get_target_expr_sfinae, we end up
issuing an error in digest_init_r:
1224 if (COMPOUND_LITERAL_P (stripped_init) && code == ARRAY_TYPE)
1225 {
1226 if (complain & tf_error)
1227 error_at (loc, "cannot initialize aggregate of type %qT with "
1228 "a compound literal", type);
But I hope the rest of the patch is reasonable. The LOOKUP_NO_NARROWING bit
isn't necessary but it should be a correct thing to do, so that later in
perform_implicit_conversion_flags we properly set the recently added flag
IMPLICIT_CONV_EXPR_BRACED_INIT.
Bootstrapped/regtested on x86_64-linux and ppc64le-linux, ok for trunk?
2019-02-16 Marek Polacek <pola...@redhat.com>
PR c++/89217 - ICE with list-initialization in range-based for loop.
* constexpr.c (unshare_constructor): No longer static.
* cp-tree.h (unshare_constructor): Declare.
* semantics.c (finish_compound_literal): When dealing with a
non-dependent expression in a template, return the original
expression. Pass LOOKUP_NO_NARROWING to digest_init_flags.
OK.
Jason