diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2014-10-13 21:07:45 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2014-10-13 21:07:45 +0000 |
| commit | 12f7ef39ce36dc712387bb0a14fe7e4714138eb7 (patch) | |
| tree | e788d0d348c5ce47510434a41793548117973af7 /clang/lib | |
| parent | b44ad60835fd3663e135ed231a5791f4efc21861 (diff) | |
| download | bcm5719-llvm-12f7ef39ce36dc712387bb0a14fe7e4714138eb7.tar.gz bcm5719-llvm-12f7ef39ce36dc712387bb0a14fe7e4714138eb7.zip | |
Objective-C [Sema]. Fixes a bug in comparing qualified
Objective-C pointer types. In this case, checker incorrectly
claims incompatible pointer types if redundant protocol conformance
is specified. rdar://18491222
llvm-svn: 219630
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 78 |
1 files changed, 30 insertions, 48 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 577e82089b8..09638916cf0 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -6742,58 +6742,40 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS, if (LHS->getNumProtocols() == 0) return true; - // Okay, we know the LHS has protocol qualifiers. If the RHS doesn't, - // more detailed analysis is required. - if (RHS->getNumProtocols() == 0) { - // OK, if LHS is a superclass of RHS *and* - // this superclass is assignment compatible with LHS. - // false otherwise. - bool IsSuperClass = - LHS->getInterface()->isSuperClassOf(RHS->getInterface()); - if (IsSuperClass) { - // OK if conversion of LHS to SuperClass results in narrowing of types - // ; i.e., SuperClass may implement at least one of the protocols - // in LHS's protocol list. Example, SuperObj<P1> = lhs<P1,P2> is ok. - // But not SuperObj<P1,P2,P3> = lhs<P1,P2>. - llvm::SmallPtrSet<ObjCProtocolDecl *, 8> SuperClassInheritedProtocols; - CollectInheritedProtocols(RHS->getInterface(), SuperClassInheritedProtocols); - // If super class has no protocols, it is not a match. - if (SuperClassInheritedProtocols.empty()) - return false; + // Okay, we know the LHS has protocol qualifiers. But RHS may or may not. + // More detailed analysis is required. + // OK, if LHS is same or a superclass of RHS *and* + // this LHS, or as RHS's super class is assignment compatible with LHS. + bool IsSuperClass = + LHS->getInterface()->isSuperClassOf(RHS->getInterface()); + if (IsSuperClass) { + // OK if conversion of LHS to SuperClass results in narrowing of types + // ; i.e., SuperClass may implement at least one of the protocols + // in LHS's protocol list. Example, SuperObj<P1> = lhs<P1,P2> is ok. + // But not SuperObj<P1,P2,P3> = lhs<P1,P2>. + llvm::SmallPtrSet<ObjCProtocolDecl *, 8> SuperClassInheritedProtocols; + CollectInheritedProtocols(RHS->getInterface(), SuperClassInheritedProtocols); + // Also, if RHS has explicit quelifiers, include them for comparing with LHS's + // qualifiers. + for (auto *RHSPI : RHS->quals()) + SuperClassInheritedProtocols.insert(RHSPI->getCanonicalDecl()); + // If there is no protocols associated with RHS, it is not a match. + if (SuperClassInheritedProtocols.empty()) + return false; - for (const auto *LHSProto : LHS->quals()) { - bool SuperImplementsProtocol = false; - for (auto *SuperClassProto : SuperClassInheritedProtocols) { - if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) { - SuperImplementsProtocol = true; - break; - } + for (const auto *LHSProto : LHS->quals()) { + bool SuperImplementsProtocol = false; + for (auto *SuperClassProto : SuperClassInheritedProtocols) + if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) { + SuperImplementsProtocol = true; + break; } - if (!SuperImplementsProtocol) - return false; - } - return true; - } - return false; - } - - for (const auto *LHSPI : LHS->quals()) { - bool RHSImplementsProtocol = false; - - // If the RHS doesn't implement the protocol on the left, the types - // are incompatible. - for (auto *RHSPI : RHS->quals()) { - if (RHSPI->lookupProtocolNamed(LHSPI->getIdentifier())) { - RHSImplementsProtocol = true; - break; - } + if (!SuperImplementsProtocol) + return false; } - // FIXME: For better diagnostics, consider passing back the protocol name. - if (!RHSImplementsProtocol) - return false; + return true; } - // The RHS implements all protocols listed on the LHS. - return true; + return false; } bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) { |

