Objective-C++ ARC: Improve the conversion to a const __unsafe_unretained reference.

Under ARC++, a reference to a const Objective-C pointer is implicitly
treated as __unsafe_unretained, and can be initialized with (e.g.) a
__strong lvalue. Make sure this behavior does not break template
argument deduction and (related) that partial ordering still prefers a
'T* const&' template over a 'T const&' template when this case kicks
in. Fixes <rdar://problem/14467941>.

llvm-svn: 194239
This commit is contained in:
Douglas Gregor
2013-11-08 02:04:24 +00:00
parent 22626e7b49
commit c9f019ab0f
3 changed files with 37 additions and 9 deletions

View File

@@ -2687,13 +2687,16 @@ CheckOriginalCallArgDeduction(Sema &S, Sema::OriginalCallArg OriginalArg,
Qualifiers AQuals = A.getQualifiers();
Qualifiers DeducedAQuals = DeducedA.getQualifiers();
// Under Objective-C++ ARC, the deduced type may have implicitly been
// given strong lifetime. If so, update the original qualifiers to
// include this strong lifetime.
// Under Objective-C++ ARC, the deduced type may have implicitly
// been given strong or (when dealing with a const reference)
// unsafe_unretained lifetime. If so, update the original
// qualifiers to include this lifetime.
if (S.getLangOpts().ObjCAutoRefCount &&
DeducedAQuals.getObjCLifetime() == Qualifiers::OCL_Strong &&
AQuals.getObjCLifetime() == Qualifiers::OCL_None) {
AQuals.setObjCLifetime(Qualifiers::OCL_Strong);
((DeducedAQuals.getObjCLifetime() == Qualifiers::OCL_Strong &&
AQuals.getObjCLifetime() == Qualifiers::OCL_None) ||
(DeducedAQuals.hasConst() &&
DeducedAQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone))) {
AQuals.setObjCLifetime(DeducedAQuals.getObjCLifetime());
}
if (AQuals == DeducedAQuals) {
@@ -2714,7 +2717,7 @@ CheckOriginalCallArgDeduction(Sema &S, Sema::OriginalCallArg OriginalArg,
//
// Also allow conversions which merely strip [[noreturn]] from function types
// (recursively) as an extension.
// FIXME: Currently, this doesn't place nicely with qualfication conversions.
// FIXME: Currently, this doesn't play nicely with qualification conversions.
bool ObjCLifetimeConversion = false;
QualType ResultTy;
if ((A->isAnyPointerType() || A->isMemberPointerType()) &&