aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2008-06-01 02:43:50 +0000
committerSteve Naroff <snaroff@apple.com>2008-06-01 02:43:50 +0000
commit289d9f243d9074513368d27eef3b647f72a38324 (patch)
treeaf6035eded4d2cb0ee10d21fb5ac2881d61f7428
parent19b87d28317f260192d91d723b80b079711d7356 (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.cpp29
-rw-r--r--test/Sema/compatible-protocol-qualified-types.m40
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