[bug] Wrong overload chosen when a conversion operator to const T() exists

Hello,

the following snippet does compile on gcc 4.7.1, but fails with clang
trunk r165389

struct Y {};

struct X {
  operator const Y() const { return Y(); }
};

void f(Y&& y) {}

int main()
{
  f(X());
  return 0;
}

As far as I can tell, clang is right to reject this code as it would
require two user-defined conversion.

However, when another overload void f(const Y& y); is added clang still
wont accept the code. This problem also appears when using standard
library containers (vector::push_back).

Shouldn't clang choose the f(const Y&) over f(Y&&) and accept the code?

AFAIK, this behavior is reproducible on the current Apple clang 4.1 as
well.

Cheers,
Philipp Moeller
GeometryFactory

the following snippet does compile on gcc 4.7.1, but fails with clang
trunk r165389

struct Y {};

struct X {
operator const Y() const { return Y(); }
};

void f(Y&& y) {}

int main()
{
f(X());
return 0;
}

As far as I can tell, clang is right to reject this code as it would
require two user-defined conversion.

I believe there's something more general about not doing a
copy-construction in cases like this, but yeah, we're right to reject it.

However, when another overload void f(const Y& y); is added clang still
wont accept the code. This problem also appears when using standard
library containers (vector::push_back).

Shouldn't clang choose the f(const Y&) over f(Y&&) and accept the code?

Yeah. It looks like our overload resolution is somehow ignoring the qualifiers
here and therefore preferring the Y&& candidate, and then the actual call
fails.

Please file a bug.

John.

John McCall <rjmccall@apple.com> writes: