Identity and non-identity standard conversion sequences can be

compared even when one is a reference binding and the other is not
(<rdar://problem/9173984>), but the definition of an identity sequence
does not involve lvalue-to-rvalue adjustments (PR9507). Fix both
inter-related issues.

llvm-svn: 132660
This commit is contained in:
Douglas Gregor 2011-06-05 06:15:20 +00:00
parent c507db4f70
commit 377c109f21
3 changed files with 27 additions and 8 deletions

View File

@ -202,8 +202,7 @@ namespace clang {
void setAsIdentityConversion();
bool isIdentityConversion() const {
return First == ICK_Identity && Second == ICK_Identity &&
Third == ICK_Identity;
return Second == ICK_Identity && Third == ICK_Identity;
}
ImplicitConversionRank getRank() const;

View File

@ -2523,12 +2523,10 @@ compareStandardConversionSubsets(ASTContext &Context,
// 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.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)

View File

@ -503,3 +503,25 @@ namespace rdar8499524 {
g(W());
}
}
namespace rdar9173984 {
template <typename T, unsigned long N> int &f(const T (&)[N]);
template <typename T> float &f(const T *);
void test() {
int arr[2] = {0, 0};
int *arrp = arr;
int &ir = f(arr);
float &fr = f(arrp);
}
}
namespace PR9507 {
void f(int * const&); // expected-note{{candidate function}}
void f(int const(&)[1]); // expected-note{{candidate function}}
int main() {
int n[1];
f(n); // expected-error{{call to 'f' is ambiguous}}
}
}