forked from OSchip/llvm-project
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
This commit is contained in:
parent
5ad7c54bb9
commit
c9c3917a86
|
@ -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,9 +2234,21 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
|
|||
/*InOverloadResolution=*/true);
|
||||
if (Candidate.Conversions[ArgIdx].ConversionKind
|
||||
== ImplicitConversionSequence::BadConversion) {
|
||||
// 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
|
||||
// argument for which there is no corresponding parameter is
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue