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

Reply via email to