On Thu, Sep 20, 2018 at 11:53 AM, Marek Polacek <pola...@redhat.com> wrote:
> On Thu, Sep 20, 2018 at 11:25:38AM -0400, Jason Merrill wrote:
>> On Wed, Sep 19, 2018 at 9:50 PM, Marek Polacek <pola...@redhat.com> wrote:
>> > Aaaand this addresses 
>> > <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87150#c11>,
>> > as I promised earlier.  I hope I got it right.
>> >
>> > Bootstrapped/regtested on x86_64-linux, ok for trunk?
>> >
>> > 2018-09-19  Marek Polacek  <pola...@redhat.com>
>> >
>> >         PR c++/87109 - wrong ctor with maybe-rvalue semantics.
>> >         * call.c (build_user_type_conversion_1): Refine the maybe-rvalue
>> >         check to only return if we're converting from a base class.
>> >
>> >         * g++.dg/cpp0x/ref-qual19.C: Adjust the expected results.
>> >         * g++.dg/cpp0x/ref-qual20.C: New test.
>> >
>> > diff --git gcc/cp/call.c gcc/cp/call.c
>> > index ddf0ed044a0..4bbd77b9cef 100644
>> > --- gcc/cp/call.c
>> > +++ gcc/cp/call.c
>> > @@ -4034,9 +4034,13 @@ build_user_type_conversion_1 (tree totype, tree 
>> > expr, int flags,
>> >      conv->bad_p = true;
>> >
>> >    /* We're performing the maybe-rvalue overload resolution and
>> > -     a conversion function is in play.  This isn't going to work
>> > -     because we would not end up with a suitable constructor.  */
>> > -  if ((flags & LOOKUP_PREFER_RVALUE) && !DECL_CONSTRUCTOR_P (cand->fn))
>> > +     a conversion function is in play.  If we're converting from
>> > +     a base class to a derived class, reject the conversion.  */
>> > +  if ((flags & LOOKUP_PREFER_RVALUE)
>> > +      && !DECL_CONSTRUCTOR_P (cand->fn)
>> > +      && CLASS_TYPE_P (fromtype)
>> > +      && CLASS_TYPE_P (totype)
>> > +      && DERIVED_FROM_P (fromtype, totype))
>>
>> Here fromtype is the type we're converting from, and what we want to
>> reject is converting the return value of the conversion op to a base
>> class.  CLASS_TYPE_P (fromtype) will always be true, since it has a
>> conversion op.  And I think we also want to handle the case of totype
>> being a reference.
>
> I think I totally misunderstood what this was about.  It's actually about
> this case
>
> struct Y { int y; };
> struct X : public Y { int x; };
>
> struct A {
>   operator X();
> };
>
> Y
> fn (A a)
> {
>   return a;
> }
>
> where we want to avoid slicing of X when converting X to Y, yes?

Yes.

Jason

Reply via email to