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