diff options
author | Steve Naroff <snaroff@apple.com> | 2008-06-01 02:43:50 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2008-06-01 02:43:50 +0000 |
commit | 289d9f243d9074513368d27eef3b647f72a38324 (patch) | |
tree | af6035eded4d2cb0ee10d21fb5ac2881d61f7428 | |
parent | 19b87d28317f260192d91d723b80b079711d7356 (diff) |
Tweak Sema::ObjCQualifiedIdTypesAreCompatible() to handle qualified interface types on the RHS.
This eliminates a bogus warning identified in the test below.
This fixes <rdar://problem/5968256> clang on xcode: error: incompatible type initializing 'NSObject<XCSelectionSource> *', expected 'id<NSObject,XCSelectionSource>'
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51832 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 29 | ||||
-rw-r--r-- | test/Sema/compatible-protocol-qualified-types.m | 40 |
2 files changed, 64 insertions, 5 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index dd90b9ca19..2f3949fe60 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -367,14 +367,17 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, if (const ObjCQualifiedIdType *lhsQID = lhs->getAsObjCQualifiedIdType()) { const ObjCQualifiedIdType *rhsQID = rhs->getAsObjCQualifiedIdType(); const ObjCQualifiedInterfaceType *rhsQI = 0; + QualType rtype; + if (!rhsQID) { // Not comparing two ObjCQualifiedIdType's? if (!rhs->isPointerType()) return false; - QualType rtype = rhs->getAsPointerType()->getPointeeType(); - + + rtype = rhs->getAsPointerType()->getPointeeType(); rhsQI = rtype->getAsObjCQualifiedInterfaceType(); if (rhsQI == 0) { - // If the RHS is an interface pointer ('NSString*'), handle it. + // If the RHS is a unqualified interface pointer "NSString*", + // make sure we check the class hierarchy. if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) { ObjCInterfaceDecl *rhsID = IT->getDecl(); for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) { @@ -390,10 +393,10 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, } ObjCQualifiedIdType::qual_iterator RHSProtoI, RHSProtoE; - if (rhsQI) { + if (rhsQI) { // We have a qualified interface (e.g. "NSObject<Proto> *"). RHSProtoI = rhsQI->qual_begin(); RHSProtoE = rhsQI->qual_end(); - } else if (rhsQID) { + } else if (rhsQID) { // We have a qualified id (e.g. "id<Proto> *"). RHSProtoI = rhsQID->qual_begin(); RHSProtoE = rhsQID->qual_end(); } else { @@ -415,6 +418,22 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, break; } } + if (rhsQI) { + // If the RHS is a qualified interface pointer "NSString<P>*", + // make sure we check the class hierarchy. + if (const ObjCInterfaceType *IT = rtype->getAsObjCInterfaceType()) { + ObjCInterfaceDecl *rhsID = IT->getDecl(); + for (unsigned i = 0; i != lhsQID->getNumProtocols(); ++i) { + // when comparing an id<P> 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. + if (ClassImplementsProtocol(lhsQID->getProtocols(i), rhsID, true)) { + match = true; + break; + } + } + } + } if (!match) return false; } diff --git a/test/Sema/compatible-protocol-qualified-types.m b/test/Sema/compatible-protocol-qualified-types.m new file mode 100644 index 0000000000..2e7eb6c43b --- /dev/null +++ b/test/Sema/compatible-protocol-qualified-types.m @@ -0,0 +1,40 @@ +// RUN: clang -pedantic -fsyntax-only -verify %s +typedef signed char BOOL; + +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end + +@protocol NSCoding +- (void)encodeWithCoder:(NSCoder *)aCoder; +@end + +@interface NSObject <NSObject> {} +@end + +typedef float CGFloat; + +@interface NSResponder : NSObject <NSCoding> {} +@end + +@protocol XCSelectionSource; + +@interface XCSelection : NSResponder {} +- (NSObject <XCSelectionSource> *) source; +@end + +extern NSString * const XCActiveSelectionLevel; + +@interface XCActionManager : NSResponder {} ++defaultActionManager; +-selectionAtLevel:(NSString *const)s; +@end + +@implementation XDMenuItemsManager // expected-warning {{cannot find interface declaration for 'XDMenuItemsManager'}} ++ (void)initialize { + id<XCSelectionSource, NSObject> source = + [[[XCActionManager defaultActionManager] selectionAtLevel:XCActiveSelectionLevel] source]; +} +@end |