An identity conversion is better than any non-identity
conversion. Fixes PR7095.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104476 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index abbf393..6c64905 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2076,6 +2076,15 @@
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;
diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h
index 8d261dd..eb4fc65 100644
--- a/lib/Sema/SemaOverload.h
+++ b/lib/Sema/SemaOverload.h
@@ -177,6 +177,12 @@
}
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;
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 79c74ce..9618ea2 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -430,3 +430,17 @@
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); }
+}