On 2/4/19 3:48 PM, Marek Polacek wrote:
In this test we have a user-defined conversion converting const int & to
T, and we're binding a const int to const int & -- the parameter of the
converting ctor. We call Func with "VIEW_CONVERT_EXPR<const int>(Val)"
as an argument. I like to use a diagram for the conversion like this:
ck_rvalue <- ck_user <- ck_identity
T T const int
V_C_E<const int>(Val)
when processing the ck_user part we call __ct_comp, whose ICS for its
argument is
ck_ref_bind <- ck_identity
const int & <- const int
V_C_E<const int>(Val)
this ICS comes from reference_binding, and at that time we still had "Val"
so need_temporary_p is 0. But when processing the ck_user conversion
before calling build_over_call for the __ct_comp, we call
7009 expr = mark_rvalue_use (expr);
for the argument which turns the V_C_E to NON_LVALUE_EXPR<42>. Binding
"42" to const int & is possible, but requires a temporary, which we don't
create precisely because need_temporary_p is 0. I.e. the original expr
of the conversion changed behind reference_binding's back.
Now, the call to mark_rvalue_use was added in r159096 to handle
-Wunused-but-set-variable. Since r261121, we're actually able to turn a V_C_E
into an rvalue. But it seems we shouldn't be trying to turn the argument into
an rvalue in the ck_user case; mark_lvalue_use should do the job (= mark is as
used) without changing an lvalue into an rvalue, breaking the ICS as above.
I'm not sure if I'm describing the issue clearly enough, but I hope this
will do.
Yes, thanks, mark_rvalue_use is definitely wrong here. But
mark_lvalue_use might be wrong as well; we don't know here how the
expression is used by the inner conversions for the user-defined
conversion. Can we remove the call entirely? It doesn't seem to break
any Wunused* tests.
Jason