diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-09-28 19:06:58 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-09-28 19:06:58 +0000 |
commit | c9c3917a864ea6ceab413fd0dce2824fdc6dbfd5 (patch) | |
tree | ed6872d173f34c67ec50379a3644597cff8b27be | |
parent | 5ad7c54bb96bc964903f6cf60519eb5ec8009aca (diff) | |
download | bcm5719-llvm-c9c3917a864ea6ceab413fd0dce2824fdc6dbfd5.tar.gz bcm5719-llvm-c9c3917a864ea6ceab413fd0dce2824fdc6dbfd5.zip |
Multiple conversions to the same type are ambiguous but for the
purpose of overload resolution is to be treated as a uner-defined
conversion.
llvm-svn: 83004
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 18 | ||||
-rw-r--r-- | clang/test/SemaCXX/ambig-user-defined-conversions.cpp | 42 |
2 files changed, 48 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 793041b9b71..885f59c5aac 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1511,8 +1511,6 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion( return OR_Deleted; case OR_Ambiguous: - // FIXME: See C++ [over.best.ics]p10 for the handling of - // ambiguous conversion sequences. return OR_Ambiguous; } @@ -2236,8 +2234,20 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, /*InOverloadResolution=*/true); if (Candidate.Conversions[ArgIdx].ConversionKind == ImplicitConversionSequence::BadConversion) { - Candidate.Viable = false; - break; + // 13.3.3.1-p10 If several different sequences of conversions exist that + // each convert the argument to the parameter type, the implicit conversion + // sequence associated with the parameter is defined to be the unique conversion + // sequence designated the ambiguous conversion sequence. For the purpose of + // ranking implicit conversion sequences as described in 13.3.3.2, the ambiguous + // conversion sequence is treated as a user-defined sequence that is + // indistinguishable from any other user-defined conversion sequence + if (Candidate.Conversions[ArgIdx].ConversionFunctionSet.size() > 0) + Candidate.Conversions[ArgIdx].ConversionKind = + ImplicitConversionSequence::UserDefinedConversion; + else { + Candidate.Viable = false; + break; + } } } else { // (C++ 13.3.2p2): For the purposes of overload resolution, any diff --git a/clang/test/SemaCXX/ambig-user-defined-conversions.cpp b/clang/test/SemaCXX/ambig-user-defined-conversions.cpp index 1117253d367..94598f0e8ef 100644 --- a/clang/test/SemaCXX/ambig-user-defined-conversions.cpp +++ b/clang/test/SemaCXX/ambig-user-defined-conversions.cpp @@ -1,10 +1,11 @@ // RUN: clang-cc -fsyntax-only -verify %s +// Test1 struct BASE { - operator int &(); // expected-note 4 {{candidate function}} + operator int &(); // expected-note {{candidate function}} }; struct BASE1 { - operator int &(); // expected-note 4 {{candidate function}} + operator int &(); // expected-note {{candidate function}} }; struct B : public BASE, BASE1 { @@ -14,13 +15,38 @@ struct B : public BASE, BASE1 { extern B f(); B b1; -void func(const int ci, const char cc); // expected-note {{function not viable because of ambiguity in conversion of argument 1}} -void func(const char ci, const B b); // expected-note {{function not viable because of ambiguity in conversion of argument 1}} -void func(const B b, const int ci); // expected-note {{function not viable because of ambiguity in conversion of argument 2}} +void func(const int ci, const char cc); // expected-note {{candidate function}} +void func(const char ci, const B b); // expected-note {{candidate function}} +void func(const B b, const int ci); // expected-note {{candidate function}} - -const int main() { - func(b1, f()); // expected-error {{no matching function for call to 'func'}} +const int Test1() { + func(b1, f()); // expected-error {{call to 'func' is ambiguous}} return f(); // expected-error {{conversion from 'struct B' to 'int const' is ambiguous}} } + +// Test2 +struct E; +struct A { + A (E&); +}; + +struct E { + operator A (); +}; + +struct C { + C (E&); +}; + +void f1(A); // expected-note {{candidate function}} +void f1(C); // expected-note {{candidate function}} + +void Test2() +{ + E b; + f1(b); // expected-error {{call to 'f1' is ambiguous}} + // ambiguous because b -> C via constructor and + // b → A via constructor or conversion function. +} + |