From: Daniel Dunbar Date: Sat, 30 Oct 2010 19:22:48 +0000 (+0000) Subject: Revert r117678, "Qualified 'id' should implement all of static class type's", it... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2e8994e5549455d62b1b8b2ad2dc6ebbf544d3c4;p=clang Revert r117678, "Qualified 'id' should implement all of static class type's", it breaks things. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117829 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 107dafe70a..99023eeb7a 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4404,17 +4404,33 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, if (const ObjCObjectPointerType *lhsOPT = lhs->getAsObjCInterfacePointerType()) { - // If both the right and left sides have qualifiers. + if (lhsOPT->qual_empty()) { + bool match = false; + if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) { + for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(), + E = rhsQID->qual_end(); I != E; ++I) { + // when comparing an id

on rhs with a static type on lhs, + // static class must implement all of id's protocols directly or + // indirectly through its super class. + if (lhsID->ClassImplementsProtocol(*I, true)) { + match = true; + break; + } + } + if (!match) + return false; + } + return true; + } + // Both the right and left sides have qualifiers. for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(), E = lhsOPT->qual_end(); I != E; ++I) { ObjCProtocolDecl *lhsProto = *I; bool match = false; - // when comparing an id

on rhs with a static type on lhs, + // when comparing an id

on lhs with a static type on rhs, // see if static class implements all of id's protocols, directly or // through its super class and categories. - // First, lhs protocols in the qualifier list must be found, direct - // or indirect in rhs's qualifier list or it is a mismatch. for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(), E = rhsQID->qual_end(); J != E; ++J) { ObjCProtocolDecl *rhsProto = *J; @@ -4427,35 +4443,6 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, if (!match) return false; } - - // Static class's protocols, or its super class or category protocols - // must be found, direct or indirect in rhs's qualifier list or it is a mismatch. - if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) { - llvm::SmallPtrSet LHSInheritedProtocols; - CollectInheritedProtocols(lhsID, LHSInheritedProtocols); - // This is rather dubious but matches gcc's behavior. If lhs has - // no type qualifier and its class has no static protocol(s) assume - // assume that it is mismatch. - if (LHSInheritedProtocols.empty() && lhsOPT->qual_empty()) - return false; - for (llvm::SmallPtrSet::iterator I = - LHSInheritedProtocols.begin(), - E = LHSInheritedProtocols.end(); I != E; ++I) { - bool match = false; - ObjCProtocolDecl *lhsProto = (*I); - for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(), - E = rhsQID->qual_end(); J != E; ++J) { - ObjCProtocolDecl *rhsProto = *J; - if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) || - (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) { - match = true; - break; - } - } - if (!match) - return false; - } - } return true; } return false; diff --git a/test/SemaObjC/comptypes-10.m b/test/SemaObjC/comptypes-10.m deleted file mode 100644 index 0a2219099f..0000000000 --- a/test/SemaObjC/comptypes-10.m +++ /dev/null @@ -1,34 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -//rdar: //8591619 -// pr8453 - -@protocol NSCopying @end -@protocol NSPROTO @end -@protocol NSPROTO1 @end -@protocol NSPROTO2 @end - -@interface NSObject { - Class isa; -} -@end - -void gorf(NSObject *); // expected-note {{passing argument to parameter here}} - -NSObject *foo(id bar, id id_obj) -{ - NSObject *Init = bar; // expected-warning {{initializing 'NSObject *' with an expression of incompatible type 'id'}} - NSObject *Init1 = bar; // expected-warning {{initializing 'NSObject *' with an expression of incompatible type 'id'}} - - NSObject *I = id_obj; - NSObject *I1 = id_obj; - gorf(bar); // expected-warning {{passing 'id' to parameter of incompatible type 'NSObject *'}} - - gorf(id_obj); - - return bar; // expected-warning {{returning 'id' from a function with incompatible result type 'NSObject *'}} -} - -void test(id bar) -{ - NSObject *Init = bar; // expected-warning {{initializing 'NSObject *' with an expression of incompatible type 'id'}} -}