C++ PATCH for c++/89705 - ICE with reference binding with conversion function

Marek Polacek polacek@redhat.com
Thu Mar 21 21:03:00 GMT 2019


On Thu, Mar 21, 2019 at 04:13:29PM -0400, Jason Merrill wrote:
> On 3/16/19 4:53 PM, Marek Polacek wrote:
> > Here we have code like
> > 
> >    struct X { operator const int(); };
> >    int&& rri = X();
> > 
> > which I think is invalid, because [dcl.init.ref] says that if types T1 and T2
> > are reference-related, no qualifiers can be dropped, and if the reference is an
> > rvalue reference, the initializer expression can't be an lvalue.  And here the
> > result of the conversion is "const int", so the "const" would be dropped.  A
> > similar ill-formed test from the standard is
> > 
> >    struct X { operator int&(); };
> >    int&& rri = X();
> > 
> > where the result of the conversion is an lvalue of related type.  All the
> > compilers I've tried actually accept the first test, but I think that's wrong.
> 
> I don't think it is.  g++ and clang++ reject the first test if you change
> int to a class type, but prvalues of scalar type have no cv-qualifiers, so
> the result of the conversion is a prvalue of type int, which is a perfectly
> good initializer for int&&.
> 
> This is OK for the same reason:
> 
>   int&& r = (const int)42;

Oop, this is embarassing, sorry.  So I guess we're not handling the (5.3.2)
case in [dcl.init.ref] properly: "If the converted initializer is a prvalue,
its type T4 is adjusted to type “cv1 T4” ([conv.qual]) and the temporary
materialization conversion ([conv.rval]) is applied.

Marek



More information about the Gcc-patches mailing list