On Fri, Jan 12, 2018 at 2:11 PM, Nathan Sidwell <nat...@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