diff options
| author | Alex Lorenz <arphaman@gmail.com> | 2017-04-06 13:06:34 +0000 | 
|---|---|---|
| committer | Alex Lorenz <arphaman@gmail.com> | 2017-04-06 13:06:34 +0000 | 
| commit | a9832134597af6f5104806385445cdeb1f9901ed (patch) | |
| tree | 60ceb090e1872161585d251c3aa1599bcdb5cb2a /clang/lib/Sema | |
| parent | 45c936ef86d270ab85dad52dbfaf6dca319f71b0 (diff) | |
| download | bcm5719-llvm-a9832134597af6f5104806385445cdeb1f9901ed.tar.gz bcm5719-llvm-a9832134597af6f5104806385445cdeb1f9901ed.zip | |
[ObjC++] Conversions from specialized to non-specialized Objective-C generic
object types should be preferred over conversions to other object pointers
This change ensures that Clang will select the correct overload for the
following code sample:
  void overload(Base *b);
  void overload(Derived *d);
  void test(Base<Base *> b) {
    overload(b); // Select overload(Base *), not overload(Derived *)
  }
rdar://20124827
Differential Revision: https://reviews.llvm.org/D31597
llvm-svn: 299648
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 20 | 
1 files changed, 17 insertions, 3 deletions
| diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 477e04db396..c556fb7e43b 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -4047,7 +4047,7 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,          = S.Context.canAssignObjCInterfaces(ToPtr1, ToPtr2);        bool ToAssignRight          = S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1); -       +        // A conversion to an a non-id object pointer type or qualified 'id'         // type is better than a conversion to 'id'.        if (ToPtr1->isObjCIdType() && @@ -4081,11 +4081,25 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,          return ImplicitConversionSequence::Better;        //   -- "conversion of C* to B* is better than conversion of C* to A*," -      if (S.Context.hasSameType(FromType1, FromType2) &&  +      if (S.Context.hasSameType(FromType1, FromType2) &&            !FromPtr1->isObjCIdType() && !FromPtr1->isObjCClassType() && -          (ToAssignLeft != ToAssignRight)) +          (ToAssignLeft != ToAssignRight)) { +        if (FromPtr1->isSpecialized()) { +          // "conversion of B<A> * to B * is better than conversion of B * to +          // C *. +          bool IsFirstSame = +              FromPtr1->getInterfaceDecl() == ToPtr1->getInterfaceDecl(); +          bool IsSecondSame = +              FromPtr1->getInterfaceDecl() == ToPtr2->getInterfaceDecl(); +          if (IsFirstSame) { +            if (!IsSecondSame) +              return ImplicitConversionSequence::Better; +          } else if (IsSecondSame) +            return ImplicitConversionSequence::Worse; +        }          return ToAssignLeft? ImplicitConversionSequence::Worse                             : ImplicitConversionSequence::Better; +      }        //   -- "conversion of B* to A* is better than conversion of C* to A*,"        if (S.Context.hasSameUnqualifiedType(ToType1, ToType2) && | 

