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;
|
return OR_Deleted;
|
||||||
|
|
||||||
case OR_Ambiguous:
|
case OR_Ambiguous:
|
||||||
// FIXME: See C++ [over.best.ics]p10 for the handling of
|
|
||||||
// ambiguous conversion sequences.
|
|
||||||
return OR_Ambiguous;
|
return OR_Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2236,9 +2234,21 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
|
||||||
/*InOverloadResolution=*/true);
|
/*InOverloadResolution=*/true);
|
||||||
if (Candidate.Conversions[ArgIdx].ConversionKind
|
if (Candidate.Conversions[ArgIdx].ConversionKind
|
||||||
== ImplicitConversionSequence::BadConversion) {
|
== 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;
|
Candidate.Viable = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// (C++ 13.3.2p2): For the purposes of overload resolution, any
|
// (C++ 13.3.2p2): For the purposes of overload resolution, any
|
||||||
// argument for which there is no corresponding parameter is
|
// argument for which there is no corresponding parameter is
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
// RUN: clang-cc -fsyntax-only -verify %s
|
// RUN: clang-cc -fsyntax-only -verify %s
|
||||||
|
|
||||||
|
// Test1
|
||||||
struct BASE {
|
struct BASE {
|
||||||
operator int &(); // expected-note 4 {{candidate function}}
|
operator int &(); // expected-note {{candidate function}}
|
||||||
};
|
};
|
||||||
struct BASE1 {
|
struct BASE1 {
|
||||||
operator int &(); // expected-note 4 {{candidate function}}
|
operator int &(); // expected-note {{candidate function}}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct B : public BASE, BASE1 {
|
struct B : public BASE, BASE1 {
|
||||||
|
@ -14,13 +15,38 @@ struct B : public BASE, BASE1 {
|
||||||
extern B f();
|
extern B f();
|
||||||
|
|
||||||
B b1;
|
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 int ci, const char cc); // expected-note {{candidate function}}
|
||||||
void func(const char ci, const B b); // expected-note {{function not viable because of ambiguity in conversion of argument 1}}
|
void func(const char ci, const B b); // expected-note {{candidate function}}
|
||||||
void func(const B b, const int ci); // expected-note {{function not viable because of ambiguity in conversion of argument 2}}
|
void func(const B b, const int ci); // expected-note {{candidate function}}
|
||||||
|
|
||||||
|
const int Test1() {
|
||||||
const int main() {
|
func(b1, f()); // expected-error {{call to 'func' is ambiguous}}
|
||||||
func(b1, f()); // expected-error {{no matching function for call to 'func'}}
|
|
||||||
return f(); // expected-error {{conversion from 'struct B' to 'int const' 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