An identity conversion is better than any non-identity

conversion. Fixes PR7095.

llvm-svn: 104476
This commit is contained in:
Douglas Gregor 2010-05-23 22:10:15 +00:00
parent bea453a0fc
commit e87561aa2e
3 changed files with 29 additions and 0 deletions

View File

@ -2076,6 +2076,15 @@ compareStandardConversionSubsets(ASTContext &Context,
ImplicitConversionSequence::CompareKind Result
= ImplicitConversionSequence::Indistinguishable;
// the identity conversion sequence is considered to be a subsequence of
// any non-identity conversion sequence
if (SCS1.ReferenceBinding == SCS2.ReferenceBinding) {
if (SCS1.isIdentityConversion() && !SCS2.isIdentityConversion())
return ImplicitConversionSequence::Better;
else if (!SCS1.isIdentityConversion() && SCS2.isIdentityConversion())
return ImplicitConversionSequence::Worse;
}
if (SCS1.Second != SCS2.Second) {
if (SCS1.Second == ICK_Identity)
Result = ImplicitConversionSequence::Better;

View File

@ -177,6 +177,12 @@ namespace clang {
}
void setAsIdentityConversion();
bool isIdentityConversion() const {
return First == ICK_Identity && Second == ICK_Identity &&
Third == ICK_Identity;
}
ImplicitConversionRank getRank() const;
bool isPointerConversionToBool() const;
bool isPointerConversionToVoidPointer(ASTContext& Context) const;

View File

@ -430,3 +430,17 @@ namespace PR6177 {
void g() { f(""); } // expected-error{{volatile lvalue reference to type 'bool const volatile' cannot bind to a value of unrelated type 'char const [1]'}}
}
namespace PR7095 {
struct X { };
struct Y {
operator const X*();
private:
operator X*();
};
void f(const X *);
void g(Y y) { f(y); }
}