From 289d9f243d9074513368d27eef3b647f72a38324 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Sun, 1 Jun 2008 02:43:50 +0000 Subject: [PATCH] Tweak Sema::ObjCQualifiedIdTypesAreCompatible() to handle qualified interface types on the RHS. This eliminates a bogus warning identified in the test below. This fixes clang on xcode: error: incompatible type initializing 'NSObject *', expected 'id' git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51832 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExprObjC.cpp | 29 +++++++++++--- .../compatible-protocol-qualified-types.m | 40 +++++++++++++++++++ 2 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 test/Sema/compatible-protocol-qualified-types.m 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 *"). RHSProtoI = rhsQI->qual_begin(); RHSProtoE = rhsQI->qual_end(); - } else if (rhsQID) { + } else if (rhsQID) { // We have a qualified id (e.g. "id *"). 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

*", + // 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

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 {} +@end + +typedef float CGFloat; + +@interface NSResponder : NSObject {} +@end + +@protocol XCSelectionSource; + +@interface XCSelection : NSResponder {} +- (NSObject *) 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 source = + [[[XCActionManager defaultActionManager] selectionAtLevel:XCActiveSelectionLevel] source]; +} +@end -- 2.40.0