llvm-project/clang/test/SemaCXX/overload-call-copycon.cpp
Douglas Gregor 836a7e8468 Improve our handling of user-defined conversions when computing
implicit conversion sequences. In particular, model the "standard
conversion" from a class to its own type (or a base type) directly as
a standard conversion in the normal path *without* trying to determine
if there is a valid copy constructor. This appears to match the intent
of C++ [over.best.ics]p6 and more closely matches GCC and EDG.

As part of this, model non-lvalue reference initialization via
user-defined conversion in overloading the same way we handle it in
InitializationSequence, separating the "general user-defined
conversion" and "conversion to compatible class type" cases.

The churn in the overload-call-copycon.cpp test case is because the
test case was originally wrong; it assumed that we should do more
checking for copy constructors that we actually should, which affected
overload resolution.

Fixes PR7055. Bootstrapped okay.

llvm-svn: 110773
2010-08-11 02:15:33 +00:00

52 lines
1.5 KiB
C++

// RUN: %clang_cc1 -fsyntax-only -verify %s -Wnon-pod-varargs
class X { }; // expected-note {{the implicit copy constructor}} \
// expected-note{{the implicit default constructor}}
int& copycon(X x); // expected-note{{passing argument to parameter}}
float& copycon(...);
void test_copycon(X x, X const xc, X volatile xv) {
int& i1 = copycon(x);
int& i2 = copycon(xc);
copycon(xv); // expected-error{{no matching constructor}}
}
class A {
public:
A(A&); // expected-note{{would lose const qualifier}} \
// expected-note{{no known conversion}}
};
class B : public A { }; // expected-note{{would lose const qualifier}} \
// expected-note{{would lose volatile qualifier}} \
// expected-note 2{{requires 0 arguments}}
short& copycon2(A a); // expected-note{{passing argument to parameter}}
int& copycon2(B b); // expected-note 2{{passing argument to parameter}}
float& copycon2(...);
void test_copycon2(A a, const A ac, B b, B const bc, B volatile bv) {
int& i1 = copycon2(b);
copycon2(bc); // expected-error{{no matching constructor}}
copycon2(bv); // expected-error{{no matching constructor}}
short& s1 = copycon2(a);
copycon2(ac); // expected-error{{no matching constructor}}
}
int& copycon3(A a); // expected-note{{passing argument to parameter 'a' here}}
float& copycon3(...);
void test_copycon3(B b, const B bc) {
int& i1 = copycon3(b);
copycon3(bc); // expected-error{{no matching constructor}}
}
class C : public B { };
float& copycon4(A a);
int& copycon4(B b);
void test_copycon4(C c) {
int& i = copycon4(c);
};