From a8f8dac6a29f6d33474a38a32ce9dd859b696da9 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 19 Jul 2010 22:02:22 +0000 Subject: [PATCH] Patch to type match comparing Objective-C Classes which implement protocols (Radar 8191774). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108758 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTContext.h | 2 ++ lib/AST/ASTContext.cpp | 32 ++++++++++++++++++++++++- test/SemaObjC/compare-qualified-class.m | 30 +++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 test/SemaObjC/compare-qualified-class.m diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 3799451360..488cfe0929 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -1235,6 +1235,8 @@ public: bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, bool ForCompare); + bool ObjCQualifiedClassTypesAreCompatible(QualType LHS, QualType RHS); + // Check the safety of assignment from LHS to RHS bool canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, const ObjCObjectPointerType *RHSOPT); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index d41051f5dc..03e91f101e 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4226,6 +4226,32 @@ bool ASTContext::QualifiedIdConformsQualifiedId(QualType lhs, QualType rhs) { return false; } +/// ObjCQualifiedClassTypesAreCompatible - compare Class and +/// Class. +bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs, + QualType rhs) { + const ObjCObjectPointerType *lhsQID = lhs->getAs(); + const ObjCObjectPointerType *rhsOPT = rhs->getAs(); + assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible"); + + for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(), + E = lhsQID->qual_end(); I != E; ++I) { + bool match = false; + ObjCProtocolDecl *lhsProto = *I; + for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(), + E = rhsOPT->qual_end(); J != E; ++J) { + ObjCProtocolDecl *rhsProto = *J; + if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) { + match = true; + break; + } + } + if (!match) + return false; + } + return true; +} + /// ObjCQualifiedIdTypesAreCompatible - We know that one of lhs/rhs is an /// ObjCQualifiedIDType. bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs, @@ -4365,7 +4391,11 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT, return ObjCQualifiedIdTypesAreCompatible(QualType(LHSOPT,0), QualType(RHSOPT,0), false); - + + if (LHS->isObjCQualifiedClass() && RHS->isObjCQualifiedClass()) + return ObjCQualifiedClassTypesAreCompatible(QualType(LHSOPT,0), + QualType(RHSOPT,0)); + // If we have 2 user-defined types, fall into that path. if (LHS->getInterface() && RHS->getInterface()) return canAssignObjCInterfaces(LHS, RHS); diff --git a/test/SemaObjC/compare-qualified-class.m b/test/SemaObjC/compare-qualified-class.m new file mode 100644 index 0000000000..cb2b26a4f7 --- /dev/null +++ b/test/SemaObjC/compare-qualified-class.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar:// 8191774 + +@protocol SomeProtocol +@end + +@protocol SomeProtocol1 +@end + +@interface SomeObject +@end + +int main () { + Class classA; + Class classB; + Class classC; + Class classD; + void * pv = 0; + Class c = (Class)0;; + if (pv) + return classA == pv; + + if (c) + return classA == c; + + return classA == classB || classA == classC || + classC == classA || + classA == classD; // expected-warning {{comparison of distinct pointer types ('Class *' and 'Class *')}} +} + -- 2.40.0