Fix a gcc compatibility issue which allows more protocol-qualified id on RHS to be
assigned to less protocol qualified object on LHS.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51956 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index c9cfc92..108ff3c 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -327,13 +327,21 @@
 /// lookupCategory is true). 
 static bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
                                     ObjCInterfaceDecl *IDecl, 
-                                    bool lookupCategory) {
+                                    bool lookupCategory,
+                                    bool RHSIsQualifiedID = false) {
   
   // 1st, look up the class.
   ObjCProtocolDecl **protoList = IDecl->getReferencedProtocols();
   for (unsigned i = 0; i < IDecl->getNumIntfRefProtocols(); i++) {
     if (ProtocolCompatibleWithProtocol(lProto, protoList[i]))
       return true;
+    // This is dubious and is added to be compatible with gcc.
+    // In gcc, it is also allowed assigning a protocol-qualified 'id'
+    // type to a LHS object when protocol in qualified LHS is in list
+    // of protocols in the rhs 'id' object. This IMO, should be a bug.
+    else if (RHSIsQualifiedID &&
+             ProtocolCompatibleWithProtocol(protoList[i], lProto))
+      return true;
   }
   
   // 2nd, look up the category.
@@ -350,7 +358,8 @@
   // 3rd, look up the super class(s)
   if (IDecl->getSuperClass())
     return 
-      ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory);
+      ClassImplementsProtocol(lProto, IDecl->getSuperClass(), lookupCategory,
+                              RHSIsQualifiedID);
   
   return false;
 }
@@ -481,7 +490,7 @@
     ObjCInterfaceDecl *lhsID = IT->getDecl();
     for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
       ObjCProtocolDecl *rhsProto = rhsQID->getProtocols(j);
-      if (!ClassImplementsProtocol(rhsProto, lhsID, compare))
+      if (!ClassImplementsProtocol(rhsProto, lhsID, compare, true))
         return false;
     }
     return true;