diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 43d3816275f8..87c01075a8e4 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1082,6 +1082,7 @@ public: bool &IncompleteImpl); void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod, ObjCMethodDecl *IntfMethod); + bool QualifiedIdConformsQualifiedId(QualType LHS, QualType RHS); NamespaceDecl *GetStdNamespace(); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index d854f0b50c6d..3c209440b0cf 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -775,7 +775,9 @@ void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method, void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, ObjCMethodDecl *IntfMethodDecl) { if (!Context.typesAreCompatible(IntfMethodDecl->getResultType(), - ImpMethodDecl->getResultType())) { + ImpMethodDecl->getResultType()) && + !QualifiedIdConformsQualifiedId(IntfMethodDecl->getResultType(), + ImpMethodDecl->getResultType())) { Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_ret_types) << ImpMethodDecl->getDeclName() << IntfMethodDecl->getResultType() << ImpMethodDecl->getResultType(); @@ -785,7 +787,8 @@ void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl, for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(), IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end(); IM != EM; ++IM, ++IF) { - if (Context.typesAreCompatible((*IF)->getType(), (*IM)->getType())) + if (Context.typesAreCompatible((*IF)->getType(), (*IM)->getType()) || + QualifiedIdConformsQualifiedId((*IF)->getType(), (*IM)->getType())) continue; Diag((*IM)->getLocation(), diag::warn_conflicting_param_types) diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 0073fd9f28f2..f8475a672797 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -697,6 +697,15 @@ static bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, return false; } +/// QualifiedIdConformsQualifiedId - compare id with id +/// return true if lhs's protocols conform to rhs's protocol; false +/// otherwise. +bool Sema::QualifiedIdConformsQualifiedId(QualType lhs, QualType rhs) { + if (lhs->isObjCQualifiedIdType() && rhs->isObjCQualifiedIdType()) + return ObjCQualifiedIdTypesAreCompatible(lhs, rhs, false); + return false; +} + /// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an /// ObjCQualifiedIDType. /// FIXME: Move to ASTContext::typesAreCompatible() and friends. diff --git a/clang/test/SemaObjC/class-conforming-protocol-2.m b/clang/test/SemaObjC/class-conforming-protocol-2.m new file mode 100644 index 000000000000..7b218bdbd803 --- /dev/null +++ b/clang/test/SemaObjC/class-conforming-protocol-2.m @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +@protocol NSWindowDelegate @end + +@interface NSWindow +- (void)setDelegate:(id )anObject; +- (id ) delegate; +@end + +@protocol IBStringsTableWindowDelegate +@end + +@interface IBStringsTableWindow : NSWindow {} +@end + +@implementation IBStringsTableWindow +- (void)setDelegate:(id )delegate { +} +- (id )delegate { + return 0; +} +@end diff --git a/clang/test/SemaObjC/method-conflict.m b/clang/test/SemaObjC/method-conflict.m index 1524fbae56c7..7a9b9f0beee8 100644 --- a/clang/test/SemaObjC/method-conflict.m +++ b/clang/test/SemaObjC/method-conflict.m @@ -40,7 +40,7 @@ typedef NSUInteger XDSourceLanguage; @end @class XDSCOperation; @interface XDSCClassFormatter : NSObject { } -+ (NSUInteger) compartmentsForClassifier: (id ) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec; // expected-note {{previous definition is here}} ++ (NSUInteger) compartmentsForClassifier: (id ) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec; @end @class NSString; @implementation XDSCClassFormatter @@ -48,7 +48,6 @@ typedef NSUInteger XDSourceLanguage; + appendVisibility: (id ) element withSpecification: (XDSCDisplaySpecification *) displaySpec to: (NSMutableAttributedString *) attributedString { } -// GCC doesn't currently warn about this. -+ (NSUInteger) compartmentsForClassifier: (id ) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec { // expected-warning {{conflicting parameter types in implementation of 'compartmentsForClassifier:withSpecification:': 'id' vs 'id'}} ++ (NSUInteger) compartmentsForClassifier: (id ) classifier withSpecification: (XDSCDisplaySpecification *) displaySpec { } @end