On Thu, Sep 20, 2018 at 11:25:38AM -0400, Jason Merrill wrote:
> On Wed, Sep 19, 2018 at 9:50 PM, Marek Polacek <[email protected]> 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 <[email protected]>
> >
> > 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?
Marek