This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PR c++/83160] local ref to capture
- From: Jason Merrill <jason at redhat dot com>
- To: Nathan Sidwell <nathan at acm dot org>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 17 Jan 2018 13:44:17 -0500
- Subject: Re: [PR c++/83160] local ref to capture
- Authentication-results: sourceware.org; auth=none
- References: <4cde21ec-f32a-203c-c4b6-756e35f03738@acm.org>
On Fri, Jan 12, 2018 at 2:11 PM, Nathan Sidwell <nathan@acm.org> wrote:
> Jason,
> this fixes 83160, where we complain about not having an lvalue in things
> like:
>
> void foo () {
> const int a = 0;
> [&a] () {
> const int &b = a; // here
> };
> }
>
> The problem is that we in convert_like_real we have ref_bind->identity
> conversions, and the identity conversion calls 'mark_rvalue_use'. For a
> regular rvalue use of a 'const int' VAR_DECL, we return the VAR_DECL -- not
> collapse it to the initialized value. However, for captures, there is code
> to look through the capture when rvalue_p is true. We end up looking
> through the lambda capture, through the captured 'a' and to its initializer.
> oops.
>
> Calling mark_lvalue_use instead is also wrong, because the identity conv may
> of course be being applied to an rvalue, and we end up giving an equally
> wrong error in the opposite case. Dealing with ck_identity this way sees
> wrong -- context determines whether this is an rvalue or lvalue use.
>
> I think the solution is for the identity conv to know whether it's going to
> be the subject of a direct reference binding and call mark_lvalue_use in tha
> case. There's 2 issues with that:
>
> 1) mark_lvalue_use isn't quite right because we want to specify
> reject_builtin to the inner mark_use call. (I didn't try changing
> mark_lvalue_use to pass true, I suspected it'd break actual calls of
> builtins). Fixed by making mark_use externally reachable, and passing in an
> appropriate 'rvalue_p' parm directly. I think your recent patch to select
> between the two marking fns may be neater using this entry point?
>
> 2) I modify direct_reference_binding to look at the incoming conv, and if it
> is ck_identity set that conv's rvaluedness_matches_p flag. Then deply that
> flag to determine the arg in #1. 'rvaluedness_matches_p' seemed the least
> worst existing flag to press into service here.
This makes sense to me. But I think we'd want also that flag set on
the ck_identity inside the ck_base that direct_reference_binding
creates, so setting it first rather than in an else.
Jason