[cfe-commits] r65773 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/ASTContext.cpp lib/AST/DeclObjC.cpp test/SemaObjC/protocol-typecheck.m test/SemaObjC/protocol-undef.m
Steve Naroff
snaroff at apple.com
Sun Mar 1 08:12:45 PST 2009
Author: snaroff
Date: Sun Mar 1 10:12:44 2009
New Revision: 65773
URL: http://llvm.org/viewvc/llvm-project?rev=65773&view=rev
Log:
Fix <rdar://problem/6619539> incompatible pointer types sending 'XCElementSpacer *', expected 'XCElement *' (not handling protocol signatures correctly?).
- Reworked ASTContext::canAssignObjCInterfaces().
- Added ObjCProtocolDecl::lookupProtocolNamed().
Added:
cfe/trunk/test/SemaObjC/protocol-typecheck.m
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/test/SemaObjC/protocol-undef.m
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=65773&r1=65772&r2=65773&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Sun Mar 1 10:12:44 2009
@@ -596,6 +596,8 @@
ReferencedProtocols.set(List, Num, C);
}
+ ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
+
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=65773&r1=65772&r2=65773&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sun Mar 1 10:12:44 2009
@@ -2501,33 +2501,29 @@
// Finally, we must have two protocol-qualified interfaces.
const ObjCQualifiedInterfaceType *LHSP =cast<ObjCQualifiedInterfaceType>(LHS);
const ObjCQualifiedInterfaceType *RHSP =cast<ObjCQualifiedInterfaceType>(RHS);
- ObjCQualifiedInterfaceType::qual_iterator LHSPI = LHSP->qual_begin();
- ObjCQualifiedInterfaceType::qual_iterator LHSPE = LHSP->qual_end();
- ObjCQualifiedInterfaceType::qual_iterator RHSPI = RHSP->qual_begin();
- ObjCQualifiedInterfaceType::qual_iterator RHSPE = RHSP->qual_end();
-
- // All protocols in LHS must have a presence in RHS. Since the protocol lists
- // are both sorted alphabetically and have no duplicates, we can scan RHS and
- // LHS in a single parallel scan until we run out of elements in LHS.
- assert(LHSPI != LHSPE && "Empty LHS protocol list?");
- ObjCProtocolDecl *LHSProto = *LHSPI;
-
- while (RHSPI != RHSPE) {
- ObjCProtocolDecl *RHSProto = *RHSPI++;
- // If the RHS has a protocol that the LHS doesn't, ignore it.
- if (RHSProto != LHSProto)
- continue;
-
- // Otherwise, the RHS does have this element.
- ++LHSPI;
- if (LHSPI == LHSPE)
- return true; // All protocols in LHS exist in RHS.
-
- LHSProto = *LHSPI;
- }
- // If we got here, we didn't find one of the LHS's protocols in the RHS list.
- return false;
+ // All LHS protocols must have a presence on the RHS.
+ assert(LHSP->qual_begin() != LHSP->qual_end() && "Empty LHS protocol list?");
+
+ for (ObjCQualifiedInterfaceType::qual_iterator LHSPI = LHSP->qual_begin(),
+ LHSPE = LHSP->qual_end();
+ LHSPI != LHSPE; LHSPI++) {
+ bool RHSImplementsProtocol = false;
+
+ // If the RHS doesn't implement the protocol on the left, the types
+ // are incompatible.
+ for (ObjCQualifiedInterfaceType::qual_iterator RHSPI = RHSP->qual_begin(),
+ RHSPE = RHSP->qual_end();
+ !RHSImplementsProtocol && (RHSPI != RHSPE); RHSPI++) {
+ if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier()))
+ RHSImplementsProtocol = true;
+ }
+ // FIXME: For better diagnostics, consider passing back the protocol name.
+ if (!RHSImplementsProtocol)
+ return false;
+ }
+ // The RHS implements all protocols listed on the LHS.
+ return true;
}
bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) {
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=65773&r1=65772&r2=65773&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Sun Mar 1 10:12:44 2009
@@ -412,6 +412,19 @@
ObjCContainerDecl::Destroy(C);
}
+ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
+ ObjCProtocolDecl *PDecl = this;
+
+ if (Name == getIdentifier())
+ return PDecl;
+
+ for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
+ if ((PDecl = (*I)->lookupProtocolNamed(Name)))
+ return PDecl;
+
+ return NULL;
+}
+
// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
// it inherited.
ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
Added: cfe/trunk/test/SemaObjC/protocol-typecheck.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-typecheck.m?rev=65773&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-typecheck.m (added)
+++ cfe/trunk/test/SemaObjC/protocol-typecheck.m Sun Mar 1 10:12:44 2009
@@ -0,0 +1,25 @@
+// RUN: clang -fsyntax-only -verify %s
+
+ at interface NSObject @end
+ at protocol XCElementP @end
+ at protocol XCElementSpacerP <XCElementP> @end
+
+ at protocol PWhatever @end
+
+ at interface XX
+
+- (void)setFlexElement:(NSObject <PWhatever, XCElementP> *)flexer;
+- (void)setFlexElement2:(NSObject <PWhatever, XCElementSpacerP> *)flexer;
+
+ at end
+
+void func() {
+ NSObject <PWhatever, XCElementSpacerP> * flexer;
+ NSObject <PWhatever, XCElementP> * flexer2;
+ XX *obj;
+ [obj setFlexElement:flexer];
+ // FIXME: GCC provides the following diagnostic (which is much better):
+ // protocol-typecheck.m:21: warning: class 'NSObject <PWhatever, XCElementP>' does not implement the 'XCElementSpacerP' protocol
+ [obj setFlexElement2:flexer2]; // expected-warning{{incompatible pointer types sending 'NSObject<PWhatever,XCElementP> *', expected 'NSObject<PWhatever,XCElementSpacerP> *'}}
+}
+
Modified: cfe/trunk/test/SemaObjC/protocol-undef.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-undef.m?rev=65773&r1=65772&r2=65773&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-undef.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-undef.m Sun Mar 1 10:12:44 2009
@@ -40,8 +40,7 @@
- (void)_recalculateStoredArraysForAnchor:(OzzyAnchor *)anchor {
Ozzy * contentGroup = anchor.contentGroup;
if (contentGroup == ((void *)0)) {
- // GCC doesn't warn about the following (which seems wrong).
- contentGroup = anchor; // expected-warning{{incompatible pointer types assigning 'OzzyAnchor *', expected 'Ozzy *'}}
+ contentGroup = anchor;
}
}
@end
More information about the cfe-commits
mailing list