When computing surrogates for calls to a value of object type, look

for all visible conversion functions.

llvm-svn: 93173
This commit is contained in:
Douglas Gregor 2010-01-11 19:36:35 +00:00
parent d1a8969dd2
commit 2159182078
2 changed files with 12 additions and 6 deletions

View File

@ -5741,9 +5741,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// functions for each conversion function declared in an // functions for each conversion function declared in an
// accessible base class provided the function is not hidden // accessible base class provided the function is not hidden
// within T by another intervening declaration. // within T by another intervening declaration.
// FIXME: Look in base classes for more conversion operators!
const UnresolvedSet *Conversions const UnresolvedSet *Conversions
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions(); = cast<CXXRecordDecl>(Record->getDecl())->getVisibleConversionFunctions();
for (UnresolvedSet::iterator I = Conversions->begin(), for (UnresolvedSet::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) { E = Conversions->end(); I != E; ++I) {
NamedDecl *D = *I; NamedDecl *D = *I;

View File

@ -190,16 +190,23 @@ typedef INTREF Func1(FLOAT, double);
typedef float& Func2(int, double); typedef float& Func2(int, double);
struct ConvertToFunc { struct ConvertToFunc {
operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}}
operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}}
void operator()(); void operator()();
}; };
void test_funcptr_call(ConvertToFunc ctf) { struct ConvertToFuncDerived : ConvertToFunc { };
void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) {
int &i1 = ctf(1.0f, 2.0); int &i1 = ctf(1.0f, 2.0);
float &f2 = ctf((short int)1, 1.0f); float &f1 = ctf((short int)1, 1.0f);
ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}} ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}}
ctf(); ctf();
int &i2 = ctfd(1.0f, 2.0);
float &f2 = ctfd((short int)1, 1.0f);
ctfd((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFuncDerived' is ambiguous; candidates are:}}
ctfd();
} }
struct HasMember { struct HasMember {