[cfe-commits] r117678 - in /cfe/trunk: clang.xcodeproj/project.pbxproj lib/AST/ASTContext.cpp test/SemaObjC/comptypes-10.m
Fariborz Jahanian
fjahanian at apple.com
Fri Oct 29 11:26:21 PDT 2010
Author: fjahanian
Date: Fri Oct 29 13:26:21 2010
New Revision: 117678
URL: http://llvm.org/viewvc/llvm-project?rev=117678&view=rev
Log:
Qualified 'id' should implement all of static class type's
protocols, including those added to class, super class
and categories; otherewise issue a warning. This fixes
pr8453.
Added:
cfe/trunk/test/SemaObjC/comptypes-10.m
Modified:
cfe/trunk/clang.xcodeproj/project.pbxproj
cfe/trunk/lib/AST/ASTContext.cpp
Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=117678&r1=117677&r2=117678&view=diff
==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Fri Oct 29 13:26:21 2010
@@ -2039,7 +2039,6 @@
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
compatibilityVersion = "Xcode 2.4";
- developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=117678&r1=117677&r2=117678&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Oct 29 13:26:21 2010
@@ -4404,33 +4404,17 @@
if (const ObjCObjectPointerType *lhsOPT =
lhs->getAsObjCInterfacePointerType()) {
- if (lhsOPT->qual_empty()) {
- bool match = false;
- if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) {
- for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(),
- E = rhsQID->qual_end(); I != E; ++I) {
- // when comparing an id<P> on rhs with a static type on lhs,
- // static class must implement all of id's protocols directly or
- // indirectly through its super class.
- if (lhsID->ClassImplementsProtocol(*I, true)) {
- match = true;
- break;
- }
- }
- if (!match)
- return false;
- }
- return true;
- }
- // Both the right and left sides have qualifiers.
+ // If both the right and left sides have qualifiers.
for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(),
E = lhsOPT->qual_end(); I != E; ++I) {
ObjCProtocolDecl *lhsProto = *I;
bool match = false;
- // when comparing an id<P> on lhs with a static type on rhs,
+ // when comparing an id<P> on rhs with a static type on lhs,
// see if static class implements all of id's protocols, directly or
// through its super class and categories.
+ // First, lhs protocols in the qualifier list must be found, direct
+ // or indirect in rhs's qualifier list or it is a mismatch.
for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
E = rhsQID->qual_end(); J != E; ++J) {
ObjCProtocolDecl *rhsProto = *J;
@@ -4443,6 +4427,35 @@
if (!match)
return false;
}
+
+ // Static class's protocols, or its super class or category protocols
+ // must be found, direct or indirect in rhs's qualifier list or it is a mismatch.
+ if (ObjCInterfaceDecl *lhsID = lhsOPT->getInterfaceDecl()) {
+ llvm::SmallPtrSet<ObjCProtocolDecl *, 8> LHSInheritedProtocols;
+ CollectInheritedProtocols(lhsID, LHSInheritedProtocols);
+ // This is rather dubious but matches gcc's behavior. If lhs has
+ // no type qualifier and its class has no static protocol(s) assume
+ // assume that it is mismatch.
+ if (LHSInheritedProtocols.empty() && lhsOPT->qual_empty())
+ return false;
+ for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I =
+ LHSInheritedProtocols.begin(),
+ E = LHSInheritedProtocols.end(); I != E; ++I) {
+ bool match = false;
+ ObjCProtocolDecl *lhsProto = (*I);
+ for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
+ E = rhsQID->qual_end(); J != E; ++J) {
+ ObjCProtocolDecl *rhsProto = *J;
+ if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
+ (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ return false;
+ }
+ }
return true;
}
return false;
Added: cfe/trunk/test/SemaObjC/comptypes-10.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/comptypes-10.m?rev=117678&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/comptypes-10.m (added)
+++ cfe/trunk/test/SemaObjC/comptypes-10.m Fri Oct 29 13:26:21 2010
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+//rdar: //8591619
+// pr8453
+
+ at protocol NSCopying @end
+ at protocol NSPROTO @end
+ at protocol NSPROTO1 @end
+ at protocol NSPROTO2 @end
+
+ at interface NSObject <NSCopying, NSPROTO, NSPROTO1> {
+ Class isa;
+}
+ at end
+
+void gorf(NSObject <NSCopying> *); // expected-note {{passing argument to parameter here}}
+
+NSObject <NSCopying> *foo(id <NSCopying> bar, id id_obj)
+{
+ NSObject <NSCopying> *Init = bar; // expected-warning {{initializing 'NSObject<NSCopying> *' with an expression of incompatible type 'id<NSCopying>'}}
+ NSObject *Init1 = bar; // expected-warning {{initializing 'NSObject *' with an expression of incompatible type 'id<NSCopying>'}}
+
+ NSObject <NSCopying> *I = id_obj;
+ NSObject *I1 = id_obj;
+ gorf(bar); // expected-warning {{passing 'id<NSCopying>' to parameter of incompatible type 'NSObject<NSCopying> *'}}
+
+ gorf(id_obj);
+
+ return bar; // expected-warning {{returning 'id<NSCopying>' from a function with incompatible result type 'NSObject<NSCopying> *'}}
+}
+
+void test(id <NSCopying, NSPROTO, NSPROTO2> bar)
+{
+ NSObject <NSCopying> *Init = bar; // expected-warning {{initializing 'NSObject<NSCopying> *' with an expression of incompatible type 'id<NSCopying,NSPROTO,NSPROTO2>'}}
+}
More information about the cfe-commits
mailing list